Celery 源碼解析八:State 和 Result


序列文章:

 

在前面幾篇解析中,我們已經看過了 Worker 是如何運行的,Task 是如何創建的,以及怎么被路由到 Worker 中,除了這些之外,我們還對流量限制,Worker 控制和 Task/Worker 產生和處理 Event 進行了介紹。但這卻不是全部,今天我將繼續和大家一起來看看 Celery 的 Task Result 和 State 相關的內容。

Task State

celery/celery/states.py 中,可以看到 Task 的所有 State

至於如果想要看 Task 的狀態轉變,那我們就需要回顧一下 Task 從產生到完成的過程,如果是一個普通的 Task 的話,那么它的執行流程應該是:

從 Producer 產生 -①-> MQ -②-> Consumer 接收 -③-> 執行策略執行 -④-> 執行完成

那么這里的 ①②③④ 有沒有設置狀態,並且狀態是啥,就是我們關注的重點了,ok,那我們就跟隨之前的腳步快速得發掘一番:

這個是同步發送消息的時候,其實也是第一次出現 state 的時候,但是這個 state 已經是 ④ 之后的狀態了,但是,無妨,我們已經知道了執行完成之后的狀態是在這里 update 的。那么對於異步的情況又是如何更新狀態的呢,那根據我們之前的 review,我們知道應該去找 AsyncResult

所以這里就是 backend 的事情啦,backend 再甩鍋給 backend Consumer,然后就是在 backend Consumer 里面干活了,最后就到了這:

這里其實雖然是調用的 on_state_change 但是,我們應該知道的一點就是在這個時候其實狀態已經變化了,那么我們就應該追述到上面的 result._iter_meta,看看里面的實現,這里我就飄過很多細節了,直接看最實際的地方:

這里可以發現,其實結果是通過 Backend 組件完成的,例如 Redis 就放在 Key 對應的 Value 中,其他的 Backend 也類似,如果沒有的話,在 Line 667 我們就知道了,狀態就是 PENDING 啦,第二個狀態捕獲!然后還有 Line 668 這里的解析結果也是值得我們一看,我直接看最后吧:

可以發現這里也是很有趣的,如果 Task 的狀態是異常狀態的話,還需要進行異常回溯,其實就是把異常信息解壓出來,展示給我們看。

那我們是時候我們去找找第三個狀態:Received 了,我們可以猜測一下大概可能出現的位置,這里就是:

這里可以發現居然是有一個 EVENT 發送出去,然后我們就應該去看看處理這個 Event 的人啦,如果你還有印象的話,那么你應該可以很容易得追蹤到:

這里你會發現你感興趣的所有東西,哈哈,其實你需要看看一個字典:

你會發現所有的狀態都可以在這里更新,哈哈。所以下面我就列一下各個 EVENT 的發出地點就好了:

如果你夠細心的話,你會發現 failedsucceeded 都是有兩處發送地點,有興趣猜測一下原因么?

Task Result

其實在前面說 State 的過程中我們已經看到了很多和 Result 有關的東西了。Result 可以認為就兩種,同步和異步的,其實也可以看成一種;但是,從另一個維度看,Result 其實也可看成成功的和失敗的,anyway,這些都是在 Result 中保存了的。

我在這里就簡單回顧看看 第三篇 中看過的內容,其實 Result 中就放了這幾樣東西:


分別是 任務ID返回值執行狀態 以及 錯誤堆棧信息,我們在調用的地方用這些信息就足夠了。

Worker State

除了 Task 有狀態之外,Worker 其實也是有狀態的,回顧我們 第一篇 的內容,Worker 的啟動過程這么冗長,所以不是說一運行就到了 Runing 狀態了,中間肯定是有各種狀態的,所以我們不妨一起來看看。

回顧一下我們之前看的一些代碼,我們應該是有講過一個叫做 HeartBeat 的組件,它的作用就是保持發送心跳,告訴其他 Worker 這個 Worker 還活着,那么這是一種狀態,除了這些狀態之外,我們還可以找到的其他 Worker 狀態有:

  • worker-offline
  • worker-online
  • worker-heartbeat

Worker-heartbeat 我們很清楚它在哪里發送出去的了,那么 Worker-onlineWorker-offline 又是在哪里發出去的呢?其實都一樣的,我們看到 Heart 這個 Bootstep

着重看看 startstop 方法,我們會發現其實調用的都是同一個地方:

一切了然於胸!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM