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 的发出地点就好了:

如果你够细心的话,你会发现 failed 和 succeeded 都是有两处发送地点,有兴趣猜测一下原因么?
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-online 和 Worker-offline 又是在哪里发出去的呢?其实都一样的,我们看到 Heart 这个 Bootstep:

着重看看 start 和 stop 方法,我们会发现其实调用的都是同一个地方:

一切了然于胸!
Celery 源码解析八:State 和 Result的更多相关文章
- Celery 源码解析三: Task 对象的实现
Task 的实现在 Celery 中你会发现有两处,一处位于 celery/app/task.py,这是第一个:第二个位于 celery/task/base.py 中,这是第二个.他们之间是有关系的, ...
- Celery 源码解析五: 远程控制管理
今天要聊的话题可能被大家关注得不过,但是对于 Celery 来说确实很有用的功能,曾经我在工作中遇到这类情况,就是我们将所有的任务都放在同一个队列里面,然后有一天突然某个同学的代码写得不对,导致大量的 ...
- Celery 源码解析六:Events 的实现
在 Celery 中,除了远程控制之外,还有一个元素可以让我们对分布式中的任务的状态有所掌控,而且从实际意义上来说,这个元素对 Celery 更为重要,这就是在本文中将要说到的 Event. 在 Ce ...
- Celery 源码解析七:Worker 之间的交互
前面对于 Celery 的分布式处理已经做了一些介绍,例如第五章的 远程控制 和第六章的 Event机制,但是,我认为这些分布式都比较简单,并没有体现出多实例之间的协同作用,所以,今天就来点更加复杂的 ...
- Celery 源码解析四: 定时任务的实现
在系列中的第二篇我们已经看过了 Celery 中的执行引擎是如何执行任务的,并且在第三篇中也介绍了任务的对象,但是,目前我们看到的都是被动的任务执行,也就是说目前执行的任务都是第三方调用发送过来的.可 ...
- jQuery 源码解析(八) 异步队列模块 Callbacks 回调函数详解
异步队列用于实现异步任务和回调函数的解耦,为ajax模块.队列模块.ready事件提供基础功能,包含三个部分:Query.Callbacks(flags).jQuery.Deferred(funct) ...
- ReactiveSwift源码解析(八) SignalProducer的代码的基本实现
在前面几篇博客中我们详细的聊了ReactiveSwift中的Bag.Event.Observer以及Signal的使用方式和代码实现.那么在接下来的这几篇博客中,我们就依附于之前博客的基础上来聊一聊S ...
- [源码解析] 并行分布式框架 Celery 之 worker 启动 (1)
[源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 目录 [源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 0x00 摘要 0x01 Celery的架 ...
- [源码解析] 并行分布式框架 Celery 之 worker 启动 (2)
[源码解析] 并行分布式框架 Celery 之 worker 启动 (2) 目录 [源码解析] 并行分布式框架 Celery 之 worker 启动 (2) 0x00 摘要 0x01 前文回顾 0x2 ...
随机推荐
- 使用 Hibernate 和 MySQL 需要知道的五件事
https://www.thoughts-on-java.org/5-things-you-need-to-know-when-using-hibernate-with-mysql/ 作者:Thorb ...
- 在Git上如何强推代码规范
引言 最近参加了“前端规范制定topic”小组,小组成员一起制定了html.css.js.es6.vue和react等规范,但规范制定好了怎么进行推广去强制执行呢,已知我们的项目都是用git做管理的, ...
- IO 调优
磁盘优化 1.增加缓存 2.优化磁盘的管理系统 3.设计合理的磁盘存储数据块 4.应用合理的RAID策略 TCP网络参数调优 网络IO优化 1.减少网络交互次数 2.减少网络传输数据量的大小 3.尽量 ...
- C语言 数组名不是指针
今天上计算机系统课的时候老师讲到了C中的聚合类型的数据结构.在解释数组名的时候说"数组名是一个指针,指向该数组的第一个元素",附上ppt(第二行): 我觉得这是不正确的,是一个常见 ...
- winform中执行任务,解决未响应界面
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { var coun ...
- 基于ElementUI的网站换主题的一些思考与实现
前言 web应用程序,切换主题,给其换肤,是一个比较常见的需求. 如何能快速的切换主题色?(只有固定的一种皮肤) 如果又想把主题色切换为以前的呢?(有多种可切换的皮肤) 该以何种方式编写标签的css属 ...
- ssh更改默认端口号及实现免密码远程登陆
近来在复习防火墙管理工具 iptables 的基本使用方法,涉及到对端口添加或删除防火墙策略的内容,之前对ssh更改默认端口号及免密码登录的方法不熟悉,这次做一个基本的总结防止自己遗忘. 错误偏差及其 ...
- Vue源码后记-其余内置指令(3)
其实吧,写这些后记我才真正了解到vue源码的精髓,之前的跑源码跟闹着玩一样. go! 之前将AST转换成了render函数,跳出来后,由于仍是字符串,所以调用了makeFunction将其转换成了真正 ...
- nodejs运行前端项目
有时候我们会创建一些小项目,只有几个简单html,没有引入一些前端框架,也没有使用webpack,那我们要如何让代码在我们本地跑起来呢? 当然是有很多种方法,IIS.wampserver等等好多都可以 ...
- R学习笔记 第五篇:数据变换和清理
在使用R的分组操作之前,首先要了解R语言包,包实质上是实现特定功能的,预先写好的代码库(library),R拥有大量的软件包,许多包都是由某一领域的专家编写的,但并不是所有的包都有很高的质量的,在使用 ...