2014-10-06 20 views
5

Zaczynam od Celery i Pythona, i mam pytanie, które jest prawdopodobnie bardzo proste, ale wydaje mi się, że nie mogę znaleźć żadnej odpowiedniej odpowiedzi w pobliżu ..Python seler: Pobieranie argumentów zadań, jeśli jest wyjątek

Jeśli mam kilka zadań, a jeden z nich wyrzuca, wyjątek, czy istnieje sposób na odzyskanie argumentów, które zostały przekazane do wspomnianego zadania?

Na przykład, jeśli chcę uzyskać pewne IP hostów postanawiamy, a ja utworzyć zadanie ...

@tasks_app.task 
def resolve_hostname(hostname): 
    return (hostname, {hst.address for hst in dns.resolver.query(hostname)}) 

... co może rzucić wyjątek, czy jest jakiś sposób na uzyskiwanie wartość tego argumentu hostname poza wywołaniem, gdy wystąpi wyjątek?

Powiedzmy grupie I zadania, takie jak:

ip_subtasks = group(
    resolve_hostname.s(hostname) for hostname in ['google.com', 
                'yahoo.com', 
                'failure.kommm'] 
)() 

ostatni (który stara się rozwiązać failure.kommm) podniesie wyjątek. Chciałbym umieścić metodę zadania selera get() wewnątrz try/catch i pokazać komunikat mówiący Coś poszło nie tak podczas próby rozwiązać failure.kommm (coś jak pokazano poniżej):

for ip_subtask in ip_subtasks: 
    try: 
     hostname, ips = ip_subtask.get(timeout=45) 
    except dns.exception.DNSException, e: 
     # I WISHED THIS WORKED: 
     logger.exception("Something happened when trying" 
         " to resolve %s" % ip_subtask.args[0]) 

Więc, to jest pytanie ... Czy istnieje sposób na pobieranie argumentów, z którymi zadanie zostało wykonane, jeśli mam instancję samego zadania?

Z góry dziękuję.

+0

Pan spojrzał na 'on_failure' obsługi? http://celery.readthedocs.org/en/latest/userguide/tasks.html#on_failure – Ngenator

+0

Mam i myślę, że to zadziała, ale nie wiem jak go użyć, gdy zadanie zostało utworzone przez dekorator jak pokazano powyżej (jak już mówiłem, jestem początkującym z Selerem) – BorrajaX

+0

Zapoznaj się z sekcją powyżej procedur obsługi, pokazuje jak to zrobić z klasą abstrakcyjną. – Ngenator

Odpowiedz

7

Aby to zrobić, można użyć narzędzia abstract class do wykonania obsługi on_failure.

from celery import Task 

class DebugTask(Task): 
    abstract = True 

    def on_failure(self, exc, task_id, args, kwargs, einfo): 
     logger.exception("Something happened when trying" 
         " to resolve %s" % args[0]) 

@tasks_app.task(base=DebugTask) 
def resolve_hostname(hostname): 
    return (hostname, {hst.address for hst in dns.resolver.query(hostname)}) 

Od docs:

on_failure(self, exc, task_id, args, kwargs, einfo) 

Parameters: 
    exc  – The exception raised by the task. 
    task_id – Unique id of the failed task. 
    args – Original arguments for the task that failed. 
    kwargs – Original keyword arguments for the task that failed. 
    einfo – ExceptionInfo instance, containing the traceback. 
Powiązane problemy