newsence
Python 非同步機制背後的確定性秘密

Python 非同步機制背後的確定性秘密

Hacker News·2 天前

這篇文章探討了 Python 的單執行緒事件迴圈如何確保任務排程的確定性,讓我們即使在併發執行的情況下,也能構建出可靠且可重現的持久化工作流。

背景

這篇文章探討了 DBOS 團隊在開發 Python 持久化工作流(Durable Execution)庫時的發現:儘管非同步編程通常被認為具有隨機性,但 Python 的 asyncio 事件迴圈在任務調度上其實具備某種程度的確定性。為了實現工作流的故障恢復與重放,系統必須保證步驟執行的順序一致,而利用 Python 事件迴圈先進先出(FIFO)的特性,開發者可以在任務進入 await 狀態前,透過裝飾器確定性地分配步驟 ID。

社群觀點

針對「Python 非同步具備秘密確定性」的說法,Hacker News 社群展開了激烈的辯論,核心爭議點在於這種確定性究竟是可靠的特性,還是不應過度依賴的實作細節。支持者認為,這種行為對於調試複雜系統非常有幫助,因為確定性的調度能減少排查隨機錯誤時需要考慮的變數。即使 I/O 操作的完成順序不可控,但至少任務的啟動順序是可預測的,這為開發者提供了一個相對穩定的執行基準,讓程式在隔離環境下的行為更加可控。

然而,許多資深開發者對此持保留態度,甚至發出嚴厲警告。反對者指出,這種確定性僅存在於從同步代碼啟動任務的瞬間,一旦任務內部開始進行網路請求或檔案讀取,後續的執行順序就會立即變得不可預測。更有留言者強調,依賴事件迴圈的 FIFO 特性是非常危險的開發習慣。雖然目前的 CPython 實作確實如此,且已穩定多年,但這並非非同步規範的一部分。例如 Trio 等其他事件迴圈實作,為了防止開發者寫出依賴特定順序的脆弱代碼,甚至會刻意將任務啟動順序隨機化。

社群中也出現了關於「實作細節與功能規範」的深度討論。有觀點認為,在缺乏正式語言規範的情況下,文件記載的行為幾乎等同於功能,但也有人反駁,過往經驗顯示,過度依賴這類隱晦特性往往會導致維護災難。當未來 Python 實作發生更迭,或是出現如 Rust 編寫的高效能運行環境時,這些「聰明」的技巧可能會成為阻礙系統升級的技術債。此外,部分討論也觸及了字典排序等類似案例,指出語言設計者有時會刻意引入不確定性,以避免開發者誤用實作細節,或防止特定類型的阻斷服務攻擊。

最後,針對持久化工作流的應用場景,有評論者質疑僅靠調度確定性是否足夠。他們認為,真正的重放可靠性應該建立在冪等性設計與更嚴謹的依賴模型上,而非寄望於底層調度器的行為。如果系統需要處理跨節點通訊或複雜的分叉邏輯,單純的 FIFO 順序將難以應對現實世界的網路延遲與隨機性,這使得該技術在生產環境中的健壯性仍存有疑慮。

延伸閱讀

  • Trio 專案:一個強調正確性與安全性的 Python 非同步庫,其設計哲學與 asyncio 有所不同,特別是在任務調度的隨機化處理上。
  • Python 官方文件中的 asyncio 低階 API 說明:其中關於 asyncio.call_soon 等函數的描述,是本文探討確定性調度的技術來源。
https://dbos.dev/blog/async-python-is-secretly-deterministic