2013-07-20 1 views
2

Я пытаюсь получить фильтр отправителя, например.celery task_success с фильтром отправителя

@celery.task 
def run_timer(crawl_start_time): 
    return crawl_start_time 

@task_success.connect 
def run_timer_success_handler(sender, result, **kwargs): 

    print '##################################' 
    print 'in run_timer_success_handler' 

Вышеприведенные отлично работает, но если я пытаюсь фильтровать по отправителю, он никогда не работает:

@task_success.connect(sender='tasks.run_timer') 
def run_timer_success_handler(sender, result, **kwargs): 

    print '##################################' 
    print 'in run_timer_success_handler' 

Я также попытался: @ task_success.connect (отправитель = 'run_timer') @ task_success.connect (sender = run_timer) @ task_success.connect (sender = globals() ['run_timer'])

Ни один из них не работает.

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

ответ

4

В этом случае лучше фильтровать функцию отправителя внутри. Нравится (-а):

@task_success.connect 
def ... 
    if sender == '...': 
     ... 

Поскольку реализация текущих сигналов о сельдере имеет проблемы, когда отправитель и работник задают разные процессы python. Потому что он преобразует отправителя в идентификатор и использует его для фильтрации, но сельдерей отправляет задачу по имени строки. Вот код проблема (celery.utils.dispatch.signals):

def _make_id(target): # pragma: no cover 
    if hasattr(target, 'im_func'): 
     return (id(target.im_self), id(target.im_func)) 
    return id(target) 

И идентификатор ('tasks.run_timer') не совпадает с идентификатором ('tasks.run_timer') из рабочего процесса. Если вы хотите, вы можете взломать его и relace идентификатор по хэш-функции

+2

Мне пришлось использовать 'sender.name', чтобы заставить это работать. –

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