Результаты Django Celery задают идентификатор задачи для чего-то читаемого человеком?

После многих дней у меня есть рабочий список сельдерея и сельдерея, и результаты сохраняются с помощью django_celery_results. Однако, когда я смотрю на запись таблицы, у нее нет никакой полезной информации.

Можно ли установить идентификатор задачи для чтения человеком?

results

один пример будет использовать демонстрационную задачу, он возвращает no, но нечитаемый идентификатор задачи

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'),
    },

Ответ 1

Легкий ответ №. Атрибут task_id генерируется автоматически. Если вы следуете за кодом в обратном направлении, основная функция, которая генерирует идентификатор, находится в kombu.utils.uuid.uuid(..), что интересно всего лишь тонкая оболочка вокруг встроенного uuid.uuid4(..).

Однако, если вы посмотрите на подпись функции:

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__.uuid, celery.utils.__init__.uuid и celery.utils.__init__.gen_unique_id.

Я не думаю, что вы сможете применять стоящие имена, так как эта функция вызывается без параметров, чтобы просто вернуть что-то уникальное.

НО

Если вы посмотрите Task.apply и Task.apply_async есть недокументированный параметр task_id!

Это позволит вам вручную указать task_id перед вызовом/созданием задачи, и пока они уникальны по всему миру, вы все равно получите все отчеты и показатели. К сожалению, я не вижу никакого простого способа изменить task_id из результата, чтобы сделать его более полезным после факта... вроде как сделать ваш текстовый ящик интерфейса немного глупым.


Если ваш проект настроен для него, вы можете использовать Наследование задачи и изменить поведение задачи таким образом. Теоретически вы должны иметь возможность перезаписывать apply и apply_async для ввода идентификатора задачи.

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

Должно сделать ваш идентификатор задачи похожим: project.tasks.add-15073315189870

Ответ 2

Реализовать пользовательский результирующий сервер, который перезаписывает _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)

Ответ 3

Try:

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

Это может помочь найти статус задачи в пользовательском интерфейсе, но для выполнения каждой задачи сельдерей всегда нужен уникальный идентификатор.