芹菜工人内省获取主机名/节点名

时间:2015-09-30 14:05:08

标签: python django celery

我想为我的Django 1.8应用程序运行py.test集成测试 一个完整的Celery 3.1设置,即具有真实队列(不是CELERY_ALWAYS_EAGER)。

要做到这一点,我需要说服工人使用我的基于服务器的测试数据库(PostgreSQL)而不是标准配置的数据库(SQlite3,它不能与第二个进程通信)。

为此,我想在首次使用数据库之前简单地修改工作进程中的DATABASES setting。 (我想保留SQlite用于其他py.test测试以及用于交互式测试的普通非测试DB。)

为此,工作人员需要认识到它在测试模式下运行而不是“正常”模式。 为了指示测试模式,我使用不同的节点名称启动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的并发配置:

  1. celery.exe(我在Windows上),
  2. worker 本身和
  3. 单个工作进程(这对我来说是相关的)。
  4. 这是对的吗?

    芹菜发送到每个进程似乎有不同的signals

    1. celeryd_init已发送至celery.exe
    2. worker_init将发送给 worker
    3. worker_process_init将发送到工作进程
    4. 这也是正确的吗?

      我在Django应用程序中向celery.py添加了以下内容:

      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。 如何获取主机名?

1 个答案:

答案 0 :(得分:1)

即使您可以使其工作,我也不建议使用工作人员名称来检测您是否处于测试模式。这将是一个黑客。

我解决了解我的代码是否在测试模式下运行的问题的方法是使用一个名为proj/test_settings.py的不同设置文件(而#34;常规"一个在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来反映我们设置调试模式的方式。