2011-10-06 15 views
22

Pod pewnymi warunkami chcę sprawić, aby zadanie selerowe nie powiodło się w ramach tego zadania. Próbowałem następujące:Jak sprawić, aby zadanie selera nie powiodło się w ramach zadania?

from celery.task import task 
from celery import states 

@task() 
def run_simulation(): 
    if some_condition: 
     run_simulation.update_state(state=states.FAILURE) 
     return False 

Jednak zadanie nadal zgłasza się udało:

sim.tasks.run_simulation Task [9235e3a7-c6d2-4219-bbc7-acf65c816e65] udało się 1.17847704887s : Fałsz

wydaje się, że państwo może być modyfikowana tylko wtedy, gdy zadanie jest uruchomiony, a po jego zakończeniu - seler zmienia stan na cokolwiek uzna to wynik (patrz this question). Czy jest jakiś sposób, bez zaniedbania zadania przez podniesienie wyjątku, aby zwrócić selerowi, że zadanie się nie powiodło?

+0

próbowałeś podnieść wyjątek od wewnątrz kodu? – hymloth

+0

@hymloth Zgłaszanie wyjątków sprawia, że ​​zadanie się nie udaje, co obejmuje wysyłanie do mnie wiadomości e-mail za każdym razem, kiedy to się dzieje - czegoś, czego chciałbym uniknąć. Przepraszam za bycie niejasnym, zmieniłem teraz pytanie. – Meilo

Odpowiedz

2

Otrzymałem interesting reply na to pytanie od Ask Solem, gdzie proponuje pomocnika "after_return", aby rozwiązać problem. To może być interesująca opcja na przyszłość.

W międzyczasie I rozwiązać ten problem, po prostu zwracając ciąg „porażka” od zadania, gdy chcę, aby go zawieść, a następnie sprawdzenie, że w następujący sposób:

result = AsyncResult(task_id) 
if result.state == 'FAILURE' or (result.state == 'SUCCESS' and result.get() == 'FAILURE'): 
    # Failure processing task 
+0

jeśli warunek może być zapisany jako 'result.state w READY_STATES | EXCEPTION_STATES: 'where' from celery.states import READY_STATES, EXCEPTION_STATES, UNREADY_STATES' –

14

lepszy sposób to zrobić jest aktualizacja stanu zadania jako FAILURE a następnie podnieść wyjątek Ignore, ponieważ zwraca żadnej wartości rejestruje zadanie jako udane, przykład:

from celery import Celery, states 
from celery.exceptions import Ignore 

app = Celery('tasks', broker='amqp://[email protected]//') 

@app.task(bind=True) 
def run_simulation(self): 
    if some_condition: 
     # manually update the task state 
     self.update_state(
      state = states.FAILURE, 
      meta = 'REASON FOR FAILURE' 
     ) 

     # ignore the task so no other state is recorded 
     raise Ignore() 
+0

Pamiętaj, że to NIE spowoduje wyzwolenia sygnału task_failure, więc żadne programy do obsługi, które chcesz do nich dołączyć, nie zostaną uruchomione, co imo nie jest dobre. –

Powiązane problemy