Получить имя работника сельдерея из задачи сельдерея?

Я хотел бы, чтобы задача сельдерея могла получить имя работника, выполняющего его, для целей регистрации. Мне нужно справиться с этим изнутри задачи, а не напрямую обращаться к брокеру. Есть ли способ сделать это? Я использую сельдерей с RabbitMQ, если это имеет значение.

4 ответа

Решение

Вам нужно использовать бильярд, который держит рабочих:

from celery import task
from billiard import current_process

@task
def getName():
    p = current_process()
    return p.index

Затем создайте глобальный словарь, который отображает ids->names при создании процесса.

Использовать celeryd_after_setup сигнал для захвата рабочего имени, как это:

from celery.signals import celeryd_after_setup

@celeryd_after_setup.connect
def capture_worker_name(sender, instance, **kwargs):
    os.environ["WORKER_NAME"] = '{0}'.format(sender)

Мне также нужно было имя рабочего для отчетов, поэтому я попробовал решение @cacois, но оно не работает с eventlet (current_process() не имеет атрибута initargs). Поэтому я оставлю свое решение здесь для будущих ссылок:

from celery import task

@task(bind=True)
def getName(self):
    return self.request.hostname

Название атрибута звучит для меня странно, но оно содержит имя, указанное с помощью опции -n при запуске работника. self работает так, как вы ожидаете от метода класса, вам не нужно указывать его при вызове функции (например, getName.delay()).

Первоначально вы искали имя, которое вы указали с флагом -n, верно? Это в массиве initargs. Вот модифицированная версия ответа, которая дает вам это:

from celery import task
from billiard import current_process

@task
def getName():
    p = current_process()
    return p.initargs[1].split('@')[1]
Другие вопросы по тегам