Halihazırda yürütülmekte olan bir görevi Celery ile iptal etmek mi?


96

Dokümanı okudum ve araştırıyorum ama doğru bir cevap bulamıyorum:

Zaten yürütülmekte olan bir görevi iptal edebilir misiniz? (görev başladığı gibi, biraz zaman alıyor ve yarı yolda iptal edilmesi gerekiyor)

Bunu Kereviz SSS belgesinden buldum

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

Ancak bunun sıraya alınmış görevleri iptal edip etmeyeceği veya bir işçi üzerinde çalışan bir işlemi öldüreceğinden emin değilim. Dökebileceğiniz her ışık için teşekkürler!

Yanıtlar:


185

iptal, görevin yürütülmesini iptal eder. Bir görev iptal edilirse, çalışanlar görevi görmezden gelir ve onu yürütmez. Kalıcı iptaller kullanmazsanız, göreviniz çalışanın yeniden başlatılmasından sonra yürütülebilir.

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

revoke, varsayılan olarak False olan bir sonlandırma seçeneğine sahiptir . Yürütülen görevi sonlandırmanız gerekirse, sonlandırmayı True olarak ayarlamanız gerekir .

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

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


3
Bu tam olarak aradığım açıklama, teşekkür ederim!
dcoffey3296

1
Bu dağıtılmış ortamda çalışıyor mu? Demek istediğim, birden fazla makinede görev yapan işçilerim varsa. Kereviz, görevin hangi makinede gerçekleştirildiğini takip ediyor mu?
ksrini

1
Öyle. İşçilerle iletişim komisyoncu aracılığıyla gerçekleşir.
mher

5
result.revoke (sonlandırmak = True) geri almaları aynı şeyi yapması gerektiğini (task_id, sonlandırmak = True)
CamHart

10
Ayrıca son Celery belgelerine göre, sonlandırma seçeneğini kullanmak "yöneticiler için son çare" dir. Son zamanlarda o çalışanda başlamış olan başka bir görevi sonlandırma riskini alırsınız.
kouk

38

Celery 3.1'de, görevleri iptal etme API'si değiştirilmiştir.

Kereviz SSS'ye göre result.revoke kullanmalısınız:

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

veya yalnızca görev kimliğine sahipseniz:

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

25

@ 0x00mh'nin yanıtı doğru, ancak son kereviz belgeleri , bu terminateseçeneği kullanmanın " yöneticiler için son çare " olduğunu söylüyor çünkü bu arada çalışmaya başlayan başka bir görevi yanlışlıkla sonlandırabilirsiniz. Muhtemelen daha iyi bir çözüm birleştiren terminate=Trueile signal='SIGUSR1'(SoftTimeLimitExceeded özel görevi ortaya çıkmasına neden olan).


2
Bu çözüm benim için çok iyi çalıştı. Görevimde SoftTimeLimitExceededyükseltildiğinde, özel temizleme mantığım ( try/ except/ aracılığıyla uygulanır finally) çağrılır. Bana göre bu, AbortableTasksunduğundan çok daha iyi ( docs.celeryproject.org/en/latest/reference/… ). İkincisi ile, bir veritabanı sonucu arka uç ihtiyaç ve el ve defalarca bunu iptal edildi olup olmadığını görmek için devam eden bir görevin durumunu kontrol etmek gerekir.
David Schneider

3
Bu nasıl daha iyi, anladığım kadarıyla süreç tarafından alınan başka bir görev varsa, yine de durdurulacak, sadece farklı bir istisna atılacak.
marxin

Ben kullanırsanız worker_prefetch_multiplier = 1başka görevler beri sonlandırarak geçerlilik kazanır - - Sadece iyi olmalı sonlandırmak birkaç uzun çalışan görevleri vardır beri bu doğru elde ettiniz? @spicyramen
maffe

1

Görevler için aşağıdaki seçeneklere bakın: time_limit , soft_time_limit (veya bunu çalışanlar için ayarlayabilirsiniz). Yalnızca yürütme zamanını kontrol etmek istemiyorsanız , apply_async yönteminin expires argümanına bakın .


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.