2013-09-18 4 views
8

Это, наверное, глупый вопрос, но это вызвало у меня тупик, исходящий из фона Ruby.Получение task_id в задаче Сельдерея

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

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

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

UPDATE 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 

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

+5

Создать экземпляр класса. 'property' являются [дескрипторами] (http://docs.python.org/2/reference/datamodel.html#implementing-descriptors), которые используются для предоставления атрибутного доступа к методам getter/setter, но они работают на уровень экземпляра. При доступе к ним из класса вы просто получаете оболочку 'property'. – Bakuriu

+1

@Bakuriu вы должны на самом деле опубликовать это как ответ :) – alecxe

+0

Из окна с буквой и вывода это выглядит как 'celery.AsyncResult' должно быть именем класса, а не экземпляром одного, а' task_id' является свойством атрибут этого класса - вот что говорит Бакуриу, я верю. – martineau

ответ

9

Короткий рассказ, в функции scan используйте scan.request.id.

См http://docs.celeryproject.org/en/latest/userguide/tasks.html?highlight=request#task-request-info

+0

Да, я думаю, я пробовал это, но это не сработало в контексте рабочего. Я попробую еще раз! – user1513388

+0

Какую версию сельдерея вы используете? Для более старой версии (я думаю, до версии 2.2) был другой способ сделать это с использованием параметров ключевого слова. –

+0

Я использую 3.0.23 (Chiastic Slide) – user1513388

12

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

Для получения значения task_id вам сначала нужно создать экземпляр этого класса, после чего доступ к asynch_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 

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

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


В property s являются descriptors используются для обеспечения атрибутах, как доступ к методам геттер/сеттер, так что вы можете получить доступ к данным, как :

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 
+0

Хм .. Я попробовал ваш пример выше, и это имеет смысл. Однако в контексте работника Сельдерей он не работает. Я думаю, потому что класс celery.AsyncResult уже создан. Поэтому, я думаю, мне нужно использовать что-то вроде «я»? – user1513388

7

Для того, чтобы сделать ваши задачи более «ОО-как», вы могли бы использовать bind аргумент, чтобы получить ссылку на self:

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

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

Celery's documentation С (на примере):

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

Смежные вопросы