celery - 在 celery 中,当任务入队时,将上下文元数据从发送方进程传递给工作人员的适当方法是什么?
问题描述
当任何 celery 任务入队时,我想添加工作人员能够使用的上下文元数据。
以下代码示例有效,但我想要一个合适的芹菜式解决方案。
from celery.signals import before_task_publish, task_prerun
@before_task_publish.connect
def receiver_before_task_publish(sender=None, headers=None, body=None, **kwargs):
task_kwags = body[1]
metadata = {"foo": "bar"}
task_kwags['__metadata__'] = metadata
@task_prerun.connect
def receiver_task_pre_run(task_id, task, *args, **kwargs):
metadata = kwargs['kwargs'].pop('__metadata__', {})
# metadata == {"foo": "bar"}
解决方案
当任务在工作人员中启动时,before_task_publish
's的内容header
在**kwargs
of 中push_request
。
def push_request(self, *args, **kwargs):
self.request_stack.push(Context(*args, **kwargs))
的构造函数中做了一些不错的事情Context
。
self.__dict__.update()
意味着我们可以访问这些值Context(metadata={'foo': 'bar'}).metadata
class Context(object)
# ...
def __init__(self, *args, **kwargs):
self.update(*args, **kwargs)
def update(self, *args, **kwargs):
return self.__dict__.update(*args, **kwargs)
任务上下文可从Task
的request
属性访问。
class Task(object):
# ...
def _get_request(self):
"""Get current request object."""
req = self.request_stack.top
if req is None:
# task was not called, but some may still expect a request
# to be there, perhaps that should be deprecated.
if self._default_request is None:
self._default_request = Context()
return self._default_request
return req
request = property(_get_request)
这意味着最终的解决方案很简单:
from celery.signals import before_task_publish, task_prerun
@before_task_publish.connect
def receiver_before_task_publish(sender=None, headers=None, body=None, **kwargs):
metadata = {"foo": "bar"}
headers['__metadata__'] = metadata
@task_prerun.connect
def receiver_task_pre_run(task_id, task, *args, **kwargs):
metadata = getattr(task.request, '__metadata__', {})
# metadata == {"foo": "bar"}
注意:task.request.__metadata__
也可以,但如果在集成信号之前任务已入队,则会失败。这样更安全。
推荐阅读
- excel - 如何根据 Excel 中另一列中的值查找列中出现频率最高的元素?
- unit-testing - 单元测试中的 Symfony 自定义存储库类
- react-native - 将导航重置为嵌套屏幕中的另一个堆栈导航器
- vba - 如何用VB更改ppt中的动作按钮颜色
- css - 为什么 .border-0 在 Bootstrap 4.0.0 中会覆盖 .border-bottom
- javascript - 如何在抽搐机器人中分离变量
- java - Java 的唯一用户 ID
- forms - 在 React 中创建状态数组
- angular - 具有基本身份验证的 Angular 5 get/post http
- c# - C# 从“锯齿状”列表中删除列表