Получение task_id в задаче Сельдерея

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

У меня есть объект, который выглядит так, когда я пытаюсь его распечатать.

print celery.AsyncResult.task_id
>>><property object at 0x10c383838>

Я ожидал, что фактическое значение свойства task_id будет напечатано здесь. Как я могу получить фактическое значение?

ОБНОВЛЕНИЕ 1

@celery.task
def scan(host):
    print celery.AsyncResult.task_id
    cmd = 'ps -ef'
    cm = shlex.split(cmd)
    scan = subprocess.check_output(cm)
    return scan

С наилучшими пожеланиями.

Ответ 2

Вы получаете доступ к property из класса, в то время как task_id является свойством экземпляров AsyncResult.

Чтобы получить значение task_id, сначала необходимо создать экземпляр этого класса, после чего доступ к async_result_instance.task_id вернет вам реальный идентификатор.

В вашем обновленном коде:

@celery.task
def scan(host):
    print celery.AsyncResult.task_id
    # ...

Здесь вы получаете доступ к классу, как я уже объяснил. То, что вы хотите, это экземпляр текущей выполняемой задачи. Вы можете использовать celery.current_task, чтобы получить текущий выполняемый объект задачи:

@celery.task
def scan(host):
    print celery.current_task.task_id

Или, если вас интересует уникальный идентификатор, используйте атрибут request оформленной функции:

@celery.task
def scan(host):
    print scan.request.id
    cmd = 'ps -ef'
    cm = shlex.split(cmd)
    # IMPORTANT: Do *not* use "scan = ..."!
    result = subprocess.check_output(cm)
    return result

Во втором случае не используйте никакую локальную переменную с именем scan, в противном случае вы получите UnboundLocalError.

(Код не проверен, поскольку у меня не установлено celery.)


property - это дескрипторы, используемые для предоставления атрибутного доступа к методам получения/установки, так что вы можете получить доступ к таким данным, как:

instance.attribute
instance.attribute = value

Но когда код выполняется, установщик или получатель могут контролировать происходящее.

Вы можете проверить это с помощью фиктивного класса:

>>> class Dummy(object):
...     @property
...     def a(self):
...             print("called the getter!")
...             return 1
... 
>>> Dummy.a
<property object at 0x7fdae86978e8>
>>> Dummy().a
called the getter!
1

Ответ 3

Чтобы сделать ваши задачи более "OO-like", вы можете использовать аргумент bind, чтобы получить ссылку на self:

@celery.task(bind=True)
def scan(self, host):
  print self.request.id

Обратите внимание, что self.request.id на самом деле является экземпляром AsyncTask. Чтобы идентификатор задачи был как строка , вы должны сделать self.request.id.__str__().

Из Документация на сельдерей (после примера):

Аргумент bind означает, что функция будет "связанным методом", чтобы вы могли обращаться к атрибутам и методам экземпляра типа задачи.