对于使用 Celery 的项目,我想测试任务的执行情况。 我知道the documentation advises to mock it,但是由于我没有使用正式客户端,所以我想检查一下一切正常的特定测试。 然后,我设置了一个非常简单的任务,该任务以 Unix套接字名称和要写入的消息作为参数:该任务打开 socket 上的连接,并写入消息并关闭连接。
在测试中, Celery worker 是通过 subprocess 启动的:我在发送任务之前将其启动,在收到任务后将其发送给SIGTERM
消息在 socket 上,然后等待进程关闭。
一切顺利:收到消息,符合预期,工作人员正确终止。
但是我发现,当测试停止时, RabbitMQ队列中仍会保留一条消息,好像从未确认该任务一样。 我通过查看 RabbitMQ 图形界面确认了这一点:在执行任务后发生“传递”,但没有“确认”。 这似乎很奇怪,因为使用默认配置the acknowledge should be sent before task execution。
在进一步的调查中,我注意到,如果在将sleep
发送给工作人员之前添加一秒钟的SIGTERM
,任务就会被确认。
我尝试使用sleep
检查有无strace
的执行情况,以下是日志:
我看到的唯一明显区别是,与sleep
一起,工作人员有时间开始与代理进行新的通信。它从EAGAIN
接收recvfrom
并发送帧"\1\0\1\0\0\0\r\0<\0P\0\0\0\0\0\0\0\1\0\316"
。
这是承认吗?为什么发生这么晚?
我为您提供了启动 Celery 工作器的参数:celery worker --app tests.functional.tasks.app --concurrency 1 --pool solo --without-heartbeat
。
--without-heartbeat
只是为了减少有或没有sleep
的执行之间的差异。否则,在执行sleep
的过程中会出现另一个 heartbeat 帧。
谢谢。