Получить имя работника сельдерея из задачи сельдерея?
Я хотел бы, чтобы задача сельдерея могла получить имя работника, выполняющего его, для целей регистрации. Мне нужно справиться с этим изнутри задачи, а не напрямую обращаться к брокеру. Есть ли способ сделать это? Я использую сельдерей с 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]