我想运行py。为我的Django 1.8应用进行集成测试一个完整的芹菜3.1设置,也就是说,有一个真正的队列(不是CELERY_ALWAYS_EAGER)。
要做到这一点,我需要说服工人使用我的基于服务器的测试DB (PostgreSQL),而不是标准配置的DB (SQlite3,它不能与第二个进程通信)。
要做到这一点,我想在第一次使用数据库之前简单地修改工作进程中的DATABASES设置。(我想保留SQlite的其他py。测试测试以及用于交互测试的正常非测试数据库。)
要做到这一点,worker需要认识到它是在测试模式下运行,而不是在"正常"模式下运行。为了指示测试模式,我使用不同的节点名称启动worker:celery worker -A myapp --concurrency=1 -n myworker --loglevel=info
与
celery worker -A myapp --concurrency=1 -n mytestworker --loglevel=info
为测试模式。
问题:我的Django应用程序中的celery.py模块如何读取输出工作的节点名(主机名,与-n
选项设置)?
似乎涉及到三个过程(我没有进一步的以上=1
之外的并发配置):
-
celery.exe
(我在Windows上), - 工作本身,和
- 单个工作进程(这对我来说是相关的)。
正确吗?
芹菜似乎向每个进程发送了不同的信号:
-
celeryd_init
被发送到celery.exe
, -
worker_init
被发送到工作器, -
worker_process_init
发送到工作进程
这也是正确的吗?
我添加了以下celery.py
在我的Django应用程序:
import celery.signals
def init_here(signal, sender):
print("call %s(sender=%s)" % (signal, sender))
@celery.signals.celeryd_init.connect
def celeryd_init(sender, instance, **kwargs):
init_here("celeryd_init", sender)
@celery.signals.worker_init.connect
def worker_init(sender, **kwargs):
init_here("worker_init", sender)
@celery.signals.worker_process_init.connect
def worker_process_init(sender, **kwargs):
init_here("worker_process_init", sender)
当我以测试模式启动worker时,如上所示,我得到以下输出(以及其他内容):
call celeryd_init(sender=celery@mytestworker)
call worker_init(sender=celery@mytestworker)
[2015-09-30 15:53:23,767: WARNING/MainProcess] celery@mytestworker ready.
[2015-09-30 15:53:24,282: WARNING/Worker-1] call worker_process_init(sender=None)
太糟糕了!相关进程Worker-1
没有收到celery@mytestworker
的相关信息。它如何获得主机名?
即使您可以让它工作,我也不建议使用工作者名称来检测您是否处于测试模式。这将是一个hack。
我解决了知道我的代码是否在测试模式下运行的问题的方式是有一个不同的设置文件,称为proj/test_settings.py
(而"常规"的是在proj/settings.py
),其中proj
是我的项目名称(与下面的PROJ
相同)。我让它创建一个设置来确定我们是否处于测试模式:
from .settings import *
PROJ_TESTING = True
该变量仅被test_settings
文件设置为true。注意,在这个test_settings.py
文件中也可能有一些行覆盖settings.py
中设置的默认值。例如,我确实有修改数据库配置和日志记录的代码。
我安排了启动测试的代码来设置环境变量DJANGO_SETTINGS_MODULE=proj.test_settings
。因为我在测试中使用的芹菜工作器是由运行我的测试的代码启动的,所以它们正在加载测试设置并以PROJ_TESTING
true运行。如果需要的话,检查测试模式,我可以这样做:
from django.conf import settings
if settings.PROJ_TESTING:
# Do what we need when we are testing.
else:
# Do something else.
这种方法反映了我们如何通过将DEBUG
设置为True
来设置调试模式。