2011-10-06 52 views
22

Trong một số điều kiện, tôi muốn thực hiện nhiệm vụ cần tây từ bên trong nhiệm vụ đó. Tôi thử như sau:Làm thế nào để thực hiện nhiệm vụ cần tây từ bên trong nhiệm vụ?

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 

Tuy nhiên, nhiệm vụ vẫn báo cáo đã thành công:

công tác sim.tasks.run_simulation [9235e3a7-c6d2-4219-bbc7-acf65c816e65] thành công trong việc 1.17847704887s : False

Dường như trạng thái chỉ có thể được sửa đổi trong khi tác vụ đang chạy và sau khi hoàn thành - cần thay đổi trạng thái thành bất kỳ kết quả nào (tham khảo this question). Có cách nào, không thất bại nhiệm vụ bằng cách nêu ra một ngoại lệ, để làm cho cần tây quay trở lại rằng nhiệm vụ đã thất bại?

+0

bạn đã cố gắng để nâng cao một ngoại lệ từ bên trong mã của bạn? – hymloth

+0

@hymloth Việc đưa ra một ngoại lệ khiến cho nhiệm vụ thất bại, bao gồm việc gửi cho tôi một email mọi lúc xảy ra - điều mà tôi muốn tránh. Xin lỗi vì không rõ ràng, tôi đã thay đổi câu hỏi ngay bây giờ. – Meilo

Trả lời

2

Tôi nhận được số interesting reply về câu hỏi này từ Ask Solem, nơi ông đề xuất xử lý 'after_return' để giải quyết vấn đề. Đây có thể là một lựa chọn thú vị cho tương lai.

Trong khi đó tôi giải quyết vấn đề này bằng cách đơn giản trả về một chuỗi 'KHÔNG THỂ' từ nhiệm vụ khi tôi muốn làm cho nó thất bại và sau đó kiểm tra cho rằng như sau:

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

bạn nếu điều kiện có thể được viết dưới dạng 'result.state trong READY_STATES | EXCEPTION_STATES: 'where' từ celery.states nhập READY_STATES, EXCEPTION_STATES, UNREADY_STATES' –

14

Một cách tốt hơn để làm điều này là để cập nhật trạng thái nhiệm vụ như FAILURE và sau đó nâng cao một ngoại lệ Ignore, vì trả lại bất kỳ giá trị sẽ ghi lại các nhiệm vụ như thành công, một ví dụ:

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

Lưu ý rằng điều này sẽ _not_ kích hoạt tín hiệu task_failure, vì vậy bất kỳ trình xử lý nào bạn muốn đính kèm vào đó sẽ không được kích hoạt, mà imo không tốt. –

Các vấn đề liên quan