2014-07-23 37 views
7

Her ikisi de celery.Task'dan devraldığım 2 özel görevim var (TaskA ve TaskB). Zamanlayıcı her şimdi TaskA'u başlatır ve TaskA, her seferinde farklı argümanlar ile N kez TaskB'u başlatır. Fakat bazı nedenlerle, bazen aynı argümanlarla aynı TaskB aynı anda iki kez yürütülür ve bu da veritabanında farklı sorunlara neden olur.Celery/Redis aynı görevde birden çok kez yürütülüyor

class TaskA(celery.Task): 

    def run(self, *args, **kwargs): 
     objects = MyModel.objects.filter(processed=False)\ 
           .values_list('id', flat=True) 
     task_b = TaskB() 
     for o in objects: 
      o.apply_async(args=[o, ]) 

class TaskB(celery.Task): 

    def run(self, obj_id, *args, **kwargs): 
     obj = MyModel.objects.get(id=obj_id) 
     # do some stuff with obj 

şeyler ben bu tür sorunları çözecektir umuduyla celery.group kullanarak çalıştı

denedim ama elimdeki tek run 2 argüman alır ve hiçbiri sağlandı söyleyerek hatalar vardı.

Bu benim celery.group kullanarak TaskB başlatmaya çalıştı nasıl:

# somewhere in TaskA 
task_b = TaskB() 
g = celery.group([task_b.s(id) for id in objects]) 
g.apply_async() 

Ben de böyle denedim: g.apply_async() önce, hemen orada görevleri infaz

# somewhere in TaskA 
task_b = TaskB() 
g = celery.group([task_b.run(id) for id in objects]) 
g.apply_async() 

.

Soru

Sorunum görevleri başlatmak nasıl geliyor mu yoksa başka bir şey mi? Bu normal bir davranış mı?

benim yerel makinede Bilgi

Ek I Redis 2.8.9 ile celery 3.1.13 çalışır RabbitMQ 3.3.4 ile celery 3.1.13 çalıştırın ve sunucuda. Yerel makinede böyle bir davranış görmüyorum, her görev bir kez yürütülür. Sunucuda, 1 - 10 arasında herhangi bir yerde, iki defa üst üste yapılan görevler görüyorum. Bunun alınan hangi argümanlar temelinde TaskB bir kilit tanıtıldı

çalışır

celery_beat: celery -A proj beat -l info 

celery1: celery -A proj worker -Q default -l info --purge -n default_worker -P eventlet -c 50 

celery2: celery -A proj worker -Q long -l info --purge -n long_worker -P eventlet -c 200 

Geçici Çözüm:

Bu benim yerel makinede ve sunucuda kereviz çalıştırmak nasıl. Yaklaşık 10 saatlik bir testten sonra, iki kez tam olarak neyin yürütüldüğünü görüyorum, ancak kilit veritabanı üzerinde çarpışmayı engelliyor. Bu, sorunumu çözüyor, ancak neden olduğunu anlamak isterim.

+0

Sizin kodunuz düzgün çalışıyor olmalı. [Kodunuzu bu gibi bir dosyaya kopyaladım] (http://pastebin.com/f1gAf4R4) ve tüm görevler TaskA(). Apply_async() 'çağrıldıktan sonra yürütüldü. Nerede bir sorun olduğunu görmek için izinizi kaydeder misiniz? – daniula

+0

geri izleme veritabanından gelir. MyModel'in 2 alanda benzersiz bir kısıtlaması var. Böylece görev ilk kez çalıştırıldığında ve yeni bir nesne oluşturduğunda, her şey iyidir, ancak aynı görev tekrar çalışır ve aynı nesneyi yeniden oluşturmaya çalışır ve 'IntegrityError' atar. – Neara

+0

Gönderdiğiniz kod ile, sorununuzu çoğaltmanız imkansız. Her görev için ayrı bir görev oluşturabileceğinden ayrı Görevler oluşturmayı deneyebilirsiniz. Deneyin: 'g = celery.group ([TaskB() .s (id) nesnelerde kimlik için])' – daniula

cevap

2

fanout_prefix ve fanout_patterns'u Kereste için Using Redis belgelerinde açıklandığı gibi ayarladınız mı? Redis ile Kereviz kullanıyorum ve bu problemi yaşamıyorum.

+0

Aynı sorunu yaşadım, bir görev diğer görevleri sıraya alıyorum ve bu diğer görevler birden çok kez seçilip yürütüldü. Açıklandığı gibi 'fanout_prefix' ve' fanout_patterns' ayarlarının yapılması sorunu çözmüş görünüyor. Kereviz 3.1.18 ve Kombu 3.0.30 Kullanımı –

İlgili konular