ยกเลิกงานที่กำลังดำเนินการกับคื่นฉ่าย?


96

ฉันอ่านเอกสารและค้นหา แต่ไม่พบคำตอบที่ตรงใจ:

คุณสามารถยกเลิกงานที่กำลังดำเนินการอยู่ได้หรือไม่? (เนื่องจากในงานได้เริ่มต้นขึ้นใช้เวลาสักครู่และจะต้องยกเลิกไปครึ่งทาง)

ฉันพบสิ่งนี้จากเอกสารที่คำถามที่พบบ่อยเกี่ยวกับผักชีฝรั่ง

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()

แต่ฉันไม่ชัดเจนว่าการดำเนินการนี้จะยกเลิกงานที่อยู่ในคิวหรือจะฆ่ากระบวนการทำงานของคนงาน ขอบคุณสำหรับแสงที่ส่องได้!

คำตอบ:


185

revokeยกเลิกการเรียกใช้งาน หากงานถูกเพิกถอนคนงานจะเพิกเฉยต่องานและไม่ดำเนินการ หากคุณไม่ได้ใช้การเพิกถอนอย่างต่อเนื่องงานของคุณสามารถดำเนินการได้หลังจากรีสตาร์ทของพนักงาน

http://docs.celeryproject.org/en/latest/userguide/workers.html#worker-persistent-revokes

เพิกถอนมีตัวเลือกยุติซึ่งเป็นเท็จโดยค่าเริ่มต้น หากคุณต้องการที่จะฆ่างานดำเนินการที่คุณต้องตั้งยุติการทรู

>>> from celery.task.control import revoke
>>> revoke(task_id, terminate=True)

http://docs.celeryproject.org/en/latest/userguide/workers.html#revoke-revoking-tasks


3
นี่คือคำอธิบายที่ฉันกำลังมองหาขอบคุณ!
dcoffey3296

1
สิ่งนี้ทำงานในสภาพแวดล้อมแบบกระจายหรือไม่ ฉันหมายถึงถ้าฉันมีคนงานในเครื่องจักรหลายเครื่องที่กำลังทำงาน คื่นฉ่ายติดตามเครื่องที่ทำงานอยู่หรือไม่?
ksrini

1
มัน. การสื่อสารกับคนงานเกิดขึ้นผ่านนายหน้า
mher

5
result.revoke (terminate = True) ควรทำเช่นเดียวกับ revoke (task_id, terminate = True)
CamHart

10
นอกจากนี้การใช้ตัวเลือกการยุติคือ "ทางเลือกสุดท้ายสำหรับผู้ดูแลระบบ" ตามเอกสาร Celery ล่าสุด คุณเสี่ยงต่อการยุติงานอื่นซึ่งเพิ่งเริ่มต้นกับคนงานนั้น
kouk

38

ใน Celery 3.1 API ของการเพิกถอนงานมีการเปลี่ยนแปลง

ตามคำถามที่พบบ่อยขึ้นฉ่ายคุณควรใช้ result.revoke:

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()

หรือถ้าคุณมีเพียงรหัสงาน:

>>> from proj.celery import app
>>> app.control.revoke(task_id)

25

คำตอบของ @ 0x00mh นั้นถูกต้องอย่างไรก็ตามเอกสารคื่นฉ่ายล่าสุดกล่าวว่าการใช้terminateตัวเลือกนี้เป็น "ทางเลือกสุดท้ายสำหรับผู้ดูแลระบบ " เนื่องจากคุณอาจยกเลิกงานอื่นโดยไม่ได้ตั้งใจซึ่งเริ่มดำเนินการในระหว่างนี้ เป็นไปได้ว่าโซลูชันที่ดีกว่าคือการรวมเข้าterminate=Trueกับsignal='SIGUSR1'(ซึ่งทำให้ข้อยกเว้น SoftTimeLimitExceeded ถูกยกขึ้นในงาน)


2
วิธีนี้ใช้ได้ผลดีสำหรับฉัน เมื่อSoftTimeLimitExceededถูกยกขึ้นในงานของฉันตรรกะการล้างข้อมูลแบบกำหนดเองของฉัน (ดำเนินการผ่านtry/ except/ finally) จะถูกเรียกใช้ สิ่งนี้ดีกว่าในมุมมองของฉันมากกว่าสิ่งที่AbortableTaskเสนอ ( docs.celeryproject.org/en/latest/reference/… ) ในกรณีหลังคุณต้องมีแบ็กเอนด์ผลลัพธ์ฐานข้อมูลและคุณต้องตรวจสอบสถานะของงานที่กำลังดำเนินอยู่ด้วยตนเองซ้ำ ๆ เพื่อดูว่าถูกยกเลิกหรือไม่
David Schneider

3
สิ่งนี้ดีกว่าอย่างไรเท่าที่ฉันเข้าใจว่ามีงานอื่นใดที่ถูกหยิบขึ้นมาโดยกระบวนการนี้มันจะถูกหยุดอยู่ดีข้อยกเว้นที่แตกต่างกันจะถูกโยนทิ้ง
marxin

หากฉันใช้worker_prefetch_multiplier = 1ตั้งแต่ฉันมีงานที่ต้องใช้งานเป็นเวลานานเพียงไม่กี่งานการยุติก็น่าจะดี - เนื่องจากไม่มีงานอื่นใดที่จะได้รับผลกระทบจากการยุติ - ฉันทำถูกต้องหรือไม่ @spicyramen
maffe

1

ดูตัวเลือกต่อไปนี้สำหรับงาน: time_limit , soft_time_limit (หรือคุณสามารถตั้งค่าสำหรับผู้ปฏิบัติงาน) หากคุณต้องการควบคุมเวลาในการดำเนินการไม่เพียงเท่านั้นโปรดดูอาร์กิวเมนต์หมดอายุของวิธีการ apply_async


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.