Django Celery结果将任务ID设置为人类可读的东西?

时间:2017-09-28 13:39:18

标签: python django-celery celery-task celerybeat

多天后,我有一个工作芹菜和芹菜击败任务列表,结果使用django_celery_results存储。但是,当我查看表记录时,它没有任何有用的信息。

是否可以将任务ID设置为人类可读的东西?

results

一个例子是使用demo任务,它返回no,但是一个不可读的任务id

tasks.py

@app.task
def test(a,b):
    return a + b
app.settings中的

调度程序

CELERYBEAT_SCHEDULE = {
    'test_task': {
        'task': 'home.tasks.test',
        'schedule': crontab(minute='*/1'),
    },

3 个答案:

答案 0 :(得分:4)

简单的答案是否定的。SelectedItem属性是自动生成的。如果你向后遵循代码,生成ID的核心函数在kombu.utils.uuid.uuid(..)中,有趣的是它只是内置uuid.uuid4(..)的一个薄包装。

但是,如果你看一下函数签名:

task_id

..似乎可以提供生成 ID的自己的功能,只要它们是唯一的,它们就可以工作。从根本上说,您必须修补:def uuid(_uuid=uuid4): """Generate unique id in UUID4 format. See Also: For now this is provided by :func:`uuid.uuid4`. """ return str(_uuid()) celery.__init__.uuidcelery.utils.__init__.uuid

我认为你不能使用有价值的名字,因为这个函数是在没有参数的情况下调用的,只是返回一些独特的东西。

<强> BUT

如果您查看Task.applyTask.apply_async,则会显示未记录的参数celery.utils.__init__.gen_unique_id

这将允许您在调用/创建任务之前手动指定task_id ,只要它们是全局唯一的,您仍将获得所有报告和指标。不幸的是,我没有看到任何简单的方法来改变结果中的task_id,以便在事后更有用......有点让你的UI文本框有点傻。

如果为其设置了项目,则可以使用“任务继承”并以此方式修改任务行为。从理论上讲,您应该能够覆盖task_idapply以注入任务的ID。

apply_async

应使您的任务ID看起来像:import time from celery import Task class NamedTask(Task): id_gen = lambda: int(time.time() * 1000) def _gen_task_id(self): return { 'task_id': '%s-%s' % ( self.name, self.id_gen())} def apply(self, *args, **kwargs): kwargs.update(self._gen_task_id()) return Task.apply(self, *args, **kwargs) def apply_async(self, *args, **kwargs): kwargs.update(self._gen_task_id()) return Task.apply_async(self, *args, **kwargs) @task(base=NamedTask) def add(x, y): return x + y

答案 1 :(得分:1)

实施自定义结果后端,覆盖_store_result以确定将结果保存到数据库的内容。

根据您使用的后端,找到celery.backends中的相关课程。

此示例扩展了 amqp 后端的结果。

class UsefulInfoBackend(AMQPBackend):
    def store_result(self, task_id, result, state,
                     traceback=None, request=None, **kwargs):
        result = super(UsefulInfoBackend, self).store_result(task_id, result, state,
                     traceback=None, request=None, **kwargs)
        result['useful_info'] = 'Very Useful! :)' # determine the rules for extraneous information here contains. 
        return result

初始化Celery时,会传递结果后端类。

celery.Celery(backend=UsefulInfoBackend)

答案 2 :(得分:-1)

尝试:

@app.task(name="periodic_test")
def test(a, b):
    return a+b

这可能有助于在UI中找到任务状态,但Celery总是需要每个任务执行的唯一ID。