2016-12-13 8 views
5

Celery 4.0.1Django 1.10を使用しており、タスクの実行に問題があります。ここではセロリの構成は次のとおりです。add_periodic_taskを使用してCelery(celerybeat)で定期的にタスクを設定する

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings') 
app = Celery('myapp') 

app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 

app.conf.BROKER_URL = 'amqp://{}:{}@{}'.format(settings.AMQP_USER, settings.AMQP_PASSWORD, settings.AMQP_HOST) 
app.conf.CELERY_DEFAULT_EXCHANGE = 'myapp.celery' 
app.conf.CELERY_DEFAULT_QUEUE = 'myapp.celery_default' 
app.conf.CELERY_TASK_SERIALIZER = 'json' 
app.conf.CELERY_ACCEPT_CONTENT = ['json'] 
app.conf.CELERY_IGNORE_RESULT = True 
app.conf.CELERY_DISABLE_RATE_LIMITS = True 
app.conf.BROKER_POOL_LIMIT = 2 

app.conf.CELERY_QUEUES = (
    Queue('myapp.celery_default'), 
    Queue('myapp.queue1'), 
    Queue('myapp.queue2'), 
    Queue('myapp.queue3'), 
) 

はその後tasks.pyに私が持っている:views.pyで

@app.task(queue='myapp.queue1') 
def my_task(some_id): 
    print("Doing something with", some_id) 

を、私は、このタスクをスケジュールする:

def my_view(request, id): 
    app.add_periodic_task(10, my_task.s(id)) 

その後、私は実行しますコマンド:

sudo systemctl start rabbitmq.service 
celery -A myapp.celery_app beat -l debug 
celery worker -A myapp.celery_app 

タスクは次のとおりです。決して予定はありません。ログには何も表示されません。私の見解では私がそうするので、仕事は働いています:

def my_view(request, id): 
    my_task.delay(id) 

タスクが実行されます。

私は手動でタスクをスケジュールする場合は、このそれが動作するように私の設定ファイルの場合:

app.conf.CELERYBEAT_SCHEDULE = { 
    'add-every-30-seconds': { 
     'task': 'tasks.my_task', 
     'schedule': 10.0, 
     'args': (66,) 
    }, 
} 

私は動的にタスクをスケジュールすることはできません。何か案が?

答えて

14

ビートスケジュールの設定が最初にロードされ、実行時に再スケジュールすることができないので、実際には、ビューレベルで定期的なタスクを定義していないことができます。

add_periodic_task()機能がにエントリを追加しますbeat_schedule舞台裏の設定、および同様の設定も手動で定期的なタスクを設定するために使用することができますすることができます:あなたはそれがwithi包まれるべきadd_periodic_task()を使用する場合は意味

app.conf.CELERYBEAT_SCHEDULE = { 
    'add-every-30-seconds': { 
     'task': 'tasks.my_task', 
     'schedule': 10.0, 
     'args': (66,) 
    }, 
} 

デフォルト:通常のcelerybeatは、単にタスクの実行を追跡docで述べたように

app = Celery() 

@app.on_after_configure.connect 
def setup_periodic_tasks(sender, **kwargs): 
    sender.add_periodic_task(10, my_task.s(66)) 

:n個セロリアプリレベルでon_after_configureハンドラとランタイム上の任意の変更は有効になりませんスケジューラはcelery.beat.PersistentSchedulerで、ローカルのshelveデータベースファイルで最後の実行時間を追跡するだけです。動的に定期的なタスクを管理し、実行時にcelerybeatのスケジュールを変更することができるようにするために

ありDjangoのデータベースでスケジュールを格納django-celery-beat延長もだ、とに便利な管理インターフェイスを提示実行時に定期的なタスクを管理する

タスクはdjangoデータベースに保持され、dbレベルのタスクモデルでスケジューラを更新できます。定期タスクを更新するたびに、このタスクテーブルのカウンタが増分され、セロリビートサービスにデータベースからスケジュールをリロードするよう指示されます。あなたのための可能な解決策は、次のように可能性があり

from django_celery_beat.models import PeriodicTask, IntervalSchedule 

schedule= IntervalSchedule.objects.create(every=10, period=IntervalSchedule.SECONDS) 
task = PeriodicTask.objects.create(interval=schedule, name='any name', task='tasks.my_task', args=json.dumps([66])) 

views.py

def update_task_view(request, id) 
    task = PeriodicTask.objects.get(name="task name") # if we suppose names are unique 
    task.args=json.dumps([id]) 
    task.save() 


EDIT:(13/01/2018)


最新release 4.1.0このticket #3958で主題に対処してきたし、「実はあなたはビューレベルで定期的なタスクを定義していません」というコメントに拾い

+0

をマージされました:することが可能ですapp-levelで 'add_periodic_task()'を使う、つまり 'task.py'で?これは、アプリケーション内で宣言されたこれらの定期的なタスクを維持するためのカプセル化のほうが優れているようです。 –

+0

実際に 'app.conf.CELERYBEAT_SCHEDULE'設定構文を使用するだけであれば、実際にはそれを使う必要はありませんが、明示的に使いたい場合は' task.py'ファイル。 – DhiaTN

+2

私は、最新のリリース(4.1.0以降)では、これに対処する必要があると思います。ここにある開発者は[#3958](https://github.com/celery/celery/pull/3958)です。 –

関連する問題