2013-07-31 12 views
11

In Celery, è possibile eseguire retry in caso di eccezione. Si può fare in questo modo:Come implementare autoretry per le attività di Celery

@task(max_retries=5) 
def div(a, b): 
    try: 
     return a/b 
    except ZeroDivisionError, exc: 
     raise div.retry(exc=exc) 

In questo caso, se si vuole dividere per zero, operazione verrà retied cinque volte. Ma devi verificare gli errori nel tuo codice esplicitamente. L'attività non verrà ripetuta se si salta il blocco try-except.

Voglio che le mie funzioni a guardare come:

@celery.task(autoretry_on=ZeroDivisionError, max_retries=5) 
def div(a, b): 
    return a/b 

risposta

10

Ho cercato questo problema per un po ', ma solo this feature request trovato.

decido di scrivere il mio decoratore per fare auto-tentativi:

def task_autoretry(*args_task, **kwargs_task): 
    def real_decorator(func): 
     @task(*args_task, **kwargs_task) 
     @functools.wraps(func) 
     def wrapper(*args, **kwargs): 
      try: 
       func(*args, **kwargs) 
      except kwargs_task.get('autoretry_on', Exception), exc: 
       wrapper.retry(exc=exc) 
     return wrapper 
    return real_decorator 

Con questo decoratore posso rewriter mio compito precedente:

@task_autoretry(autoretry_on=ZeroDivisionError, max_retries=5) 
def div(a, b): 
    return a/b 
+0

Questa perde il risultato però. Non dovrebbe restituire qualcosa? – dalore

2

ho modificato your answer a lavorare con il API Celery esistente (attualmente 3.1.17)

class MyCelery(Celery): 
    def task(self, *args_task, **opts_task): 
     def real_decorator(func): 
      sup = super(MyCelery, self).task 

      @sup(*args_task, **opts_task) 
      @functools.wraps(func) 
      def wrapper(*args, **kwargs): 
       try: 
        func(*args, **kwargs) 
       except opts_task.get('autoretry_on', Exception) as exc: 
        logger.info('Yo! We did it!') 
        wrapper.retry(exc=exc, args=args, kwargs=kwargs) 
      return wrapper 
     return real_decorator 

Quindi, nelle attività

app = MyCelery() 
app.config_from_object('django.conf:settings') 
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 

@app.task(autoretry_on=Exception) 
def mytask(): 
    raise Exception('Retrying!') 

Ciò consente di aggiungere la funzionalità autoretry_on alle attività senza dover utilizzare un decoratore separato per definire le attività.

Problemi correlati