2012-04-17 23 views
37

Ben bir işlev tanımladıysanız Kereviz (celerybeat) periyodik görevleri kaldırın: dinamik nasıl eklenir/aşağıdaki gibi

def add(x,y): 
    return x+y 

dinamik bir kereviz PeriodicTask olarak bu işlevi ekleyip en onu tekmelemek için bir yolu var mı Çalışma zamanı?

some_unique_task_id = celery.beat.schedule_task(add, run_every=crontab(minute="*/30")) 
celery.beat.start(some_unique_task_id) 

ben de durdurmak ya da benzeri bir şey (yalancı kod) ile dinamik olarak bu görevi kaldırmak isteyeyim: Ben böyle bir şey (yalancı kod) yapabilmek istiyorum

celery.beat.remove_task(some_unique_task_id) 

veya

celery.beat.stop(some_unique_task_id) 

FYI Periyodik görevleri django admin üzerinden yönetmenizi sağlayan djcelery kullanmıyorum.

cevap

18

Hayır, üzgünüm, bu normal kereviz ile mümkün değil.

Ancak, istediğinizi yapmak için kolayca genişletilebilir, örn. django-kereviz zamanlayıcı sadece bir alt sınıfı okuma ve yazma programı (üstte bazı optimizasyonlar ile) veritabanıdır.

Ayrıca Django olmayan projeler için bile django-kereviz zamanlayıcı kullanabilirsiniz. Böyle

şey:

  • yükleyin django + django-kereviz:

    $ yüklemek pip -U django django-kereviz

  • sizin celeryconfig için aşağıdaki ayarları ekleyin:

    DATABASES = { 
        'default': { 
         'NAME': 'celerybeat.db', 
         'ENGINE': 'django.db.backends.sqlite3', 
        }, 
    } 
    INSTALLED_APPS = ('djcelery',) 
    
  • Veritabanı tablolarını oluşturma : Veritabanı zamanlayıcı ile

    $ PYTHONPATH=. django-admin.py syncdb --settings=celeryconfig 
    
  • Başlangıç ​​celerybeat:

    $ PYTHONPATH=. django-admin.py celerybeat --settings=celeryconfig \ 
        -S djcelery.schedulers.DatabaseScheduler 
    

Ayrıca sigara Django için kullanılabilecek djcelerymon komutu var celerycam ve Django Yönetici web sunucusu başlatmak için projeleri

: aynı süreç, sen da güzel bir web arayüzündeki periyodik görevleri düzenlemek için kullanabilirsiniz

0 Bu soru google groups tarafından cevaplandırıldı

+1

Görev eklemek ve kaldırmak için koddan bahseder misiniz? Üzgünüm, anlamadım. –

+6

2012 ile 2016 arasındaki herhangi bir değişiklik var mı? – Tanay

32

(nedense djcelerymon Ctrl + C kullanılarak durdurulamaz için not, Ctrl + Z +% 1 öldürmek kullanmak zorunda ). Ben YAZAR DEĞİLİM

, tüm kredi

İşte Jean Mark gider bunun için uygun bir çözümdür.Onaylanan çalışma, benim senaryoda, ben Periyodik Görevi alt sınıflandırılır ve ihtiyacım gibi modele diğer alanları ekleyebilir ve ayrıca bu yüzden "sonlandırmak" yöntemi ekleyebilirsiniz beri bunun dışında bir model oluşturdu. Periyodik görevin etkinleştirilmiş özelliğini False olarak ayarlamanız ve silmeden önce kaydetmeniz gerekir. alt sınıfının tamamı bir zorunluluk değildir, schedule_every yöntemi, 'un gerçekten işe yaradığı yöntemdir. Görevinizi sonlandırmaya hazır olduğunuzda ( alt sınıfı kullanmadıysanız) görevinizi aramak için PeriodicTask.objects.filter (name = ...) kullanabilirsiniz, 'u devre dışı bırakın, sonra silin.

Bu yardımcı olur umarız!

from djcelery.models import PeriodicTask, IntervalSchedule 
from datetime import datetime 

class TaskScheduler(models.Model): 

    periodic_task = models.ForeignKey(PeriodicTask) 

    @staticmethod 
    def schedule_every(task_name, period, every, args=None, kwargs=None): 
    """ schedules a task by name every "every" "period". So an example call would be: 
     TaskScheduler('mycustomtask', 'seconds', 30, [1,2,3]) 
     that would schedule your custom task to run every 30 seconds with the arguments 1,2 and 3 passed to the actual task. 
    """ 
     permissible_periods = ['days', 'hours', 'minutes', 'seconds'] 
     if period not in permissible_periods: 
      raise Exception('Invalid period specified') 
     # create the periodic task and the interval 
     ptask_name = "%s_%s" % (task_name, datetime.datetime.now()) # create some name for the period task 
     interval_schedules = IntervalSchedule.objects.filter(period=period, every=every) 
     if interval_schedules: # just check if interval schedules exist like that already and reuse em 
      interval_schedule = interval_schedules[0] 
     else: # create a brand new interval schedule 
      interval_schedule = IntervalSchedule() 
      interval_schedule.every = every # should check to make sure this is a positive int 
      interval_schedule.period = period 
      interval_schedule.save() 
     ptask = PeriodicTask(name=ptask_name, task=task_name, interval=interval_schedule) 
     if args: 
      ptask.args = args 
     if kwargs: 
      ptask.kwargs = kwargs 
     ptask.save() 
     return TaskScheduler.objects.create(periodic_task=ptask) 

    def stop(self): 
     """pauses the task""" 
     ptask = self.periodic_task 
     ptask.enabled = False 
     ptask.save() 

    def start(self): 
     """starts the task""" 
     ptask = self.periodic_task 
     ptask.enabled = True 
     ptask.save() 

    def terminate(self): 
     self.stop() 
     ptask = self.periodic_task 
     self.delete() 
     ptask.delete() 
+1

Bu kabul edilen cevap olmalı. – kai

+1

@kai 'IntervalSchedule',' PeriodicTask' vb., 'Djcelery' sınıflarıdır ve OP,' djcelery'yi kullanmadığını söylüyor. Yine de kesinlikle yararlı. – Chris

2

Sen şişeyi ve djcelery yapılandırır bu flask-djcelery kontrol edebilirsiniz ve aynı zamanda bir ihtiyaç modeli sunar django-kereviz-vuru adında bir kütüphane bulunmaktadır taranabilir dinlenme API

2

sağlar. Dinamik olarak yeni periyodik görevler yüklemek için, kendi Zamanlayıcısı'nı oluşturmak zorundadır.

from django_celery_beat.schedulers import DatabaseScheduler 


class AutoUpdateScheduler(DatabaseScheduler): 

    def tick(self, *args, **kwargs): 
     if self.schedule_changed(): 
      print('resetting heap') 
      self.sync() 
      self._heap = None 
      new_schedule = self.all_as_schedule() 

      if new_schedule: 
       to_add = new_schedule.keys() - self.schedule.keys() 
       to_remove = self.schedule.keys() - new_schedule.keys() 
       for key in to_add: 
        self.schedule[key] = new_schedule[key] 
       for key in to_remove: 
        del self.schedule[key] 

     super(AutoUpdateScheduler, self).tick(*args, **kwargs) 

    @property 
    def schedule(self): 
     if not self._initial_read and not self._schedule: 
      self._initial_read = True 
      self._schedule = self.all_as_schedule() 

     return self._schedule 
+0

Teşekkürler. hemen işe ancak kullanarak 'to_add = [new_schedule.keys içinde tuşunun tuş()() değil self.schedule.keys anahtar varsa]' ve 'to_remove' için benzer yaptılar hile yoktu. Bu neden standart bir seçenek değil? Şimdiye kadar, Kereviz görevleri geri sayımı olan diğer Kereviz görevleri çağırır olması yaşadım. Bu bana pek iyi gelmiyor. – freethebees

İlgili konular