有没有办法以编程方式确定正在导入/运行的当前模块是在芹菜工作者的上下文中完成的?
我们已经决定在运行Celery工作器之前设置一个环境变量,并在代码中检查这个环境变量,但我想知道是否有更好的方法?
答案 0 :(得分:3)
简单,
import sys
IN_CELERY_WORKER_PROCESS = sys.argv and sys.argv[0].endswith('celery')\
and 'worker' in sys.argv
if IN_CELERY_WORKER_PROCESS:
print ('Im in Celery worker')
http://percentl.com/blog/django-how-can-i-detect-whether-im-running-celery-worker/
答案 1 :(得分:1)
根据您的用例场景的具体情况,您可以通过检查请求ID是否已设置来检测它:
@app.task(bind=True)
def foo(self):
print self.request.id
如果您将上述内容调用为foo.delay()
,则该任务将发送给工作人员,self.request.id
将设置为唯一编号。如果您将其作为foo()
调用,则会在当前流程中执行,self.request.id
将为None
。
答案 2 :(得分:1)
您可以使用current_worker_task
应用程序实例类中的Celery
属性。 Docs here.
定义了以下任务:
# whatever_app/tasks.py
celery_app = Celery(app)
@celery_app.task
def test_task():
if celery_app.current_worker_task:
return 'running in a celery worker'
return 'just running'
您可以在python shell上运行以下命令:
In [1]: from whatever_app.tasks import test_task
In [2]: test_task()
Out[2]: 'just running'
In [3]: r = test_task.delay()
In [4]: r.result
Out[4]: u'running in a celery worker'
注意:显然,test_task.delay()
成功后,您需要至少有一名芹菜工作者正在运行并配置为从whatever_app.tasks
加载任务。
答案 3 :(得分:1)
从celery 4.2开始,您还可以通过在worker_ready
信号上设置一个标志来完成此操作
在celery.py
中:
from celery.signals import worker_ready
app = Celery(...)
app.running = False
@worker_ready.connect
def set_running(*args, **kwargs):
app.running = True
现在,您可以使用全局应用程序实例在任务中进行检查 看看你是否在跑步。这对于确定使用哪个记录器可能非常有用。
答案 4 :(得分:0)
添加环境变量是检查该模块是否由芹菜工作者运行的好方法。在任务提交者流程中,我们可以设置环境变量,以标记它没有在芹菜工作者的上下文中运行。
但更好的方法可能是使用一些芹菜信号,这可能有助于了解模块是否在工作人员或任务提交者中运行。例如,worker-process-init信号被发送到每个子任务执行程序进程(在preforked模式下),并且处理程序可用于设置一些全局变量,表明它是一个工作进程。
答案 5 :(得分:0)
使用名称启动worker是一个好习惯,这样可以更容易地管理(停止/终止/重启)它们。您可以使用-n
来命名工作人员。
celery worker -l info -A test -n foo
现在,在您的脚本中,您可以使用app.control.inspect
来查看该工作程序是否正在运行。
In [22]: import test
In [23]: i = test.app.control.inspect(['foo'])
In [24]: i.app.control.ping()
Out[24]: [{'celery@foo': {'ok': 'pong'}}]