2016-04-14 5 views
4

私は、Herokuの分散環境で今後一度起動される予定のイベントをスケジュールするために必要なソフトウェア設計について質問します。HerokuのDjangoでシングルイベントをスケジュールするにはどうすればいいですか?

私は達成したいことを書く方が良いと思いますが、私は確かに研究を行い、2時間の仕事でもそれを理解することはできませんでした。

def after_6_hours(): 
    print('6 hours passed.') 


def create_game(): 
    print('Game created') 
    # of course time will be error, but that's just an example 
    scheduler.do(after_6_hours, time=now + 6) 

ので、私は何を達成したいことはcreate_gameが呼び出されたちょうど6時間後にafter_6_hours機能を実行できるようにすることです:

は、私が機能を持っているのは、私のviews.pyで言ってみましょう。さて見てわかるように、この関数は通常のclock.pyまたはtask.pyまたはetcなどのファイルから定義されています。

ここで、私のアプリケーション全体をHerokuで実行し、このジョブをこの仮想のfor-now-schedulerライブラリのキューに追加するにはどうすればよいですか?

残念ながら、Herokuの一時追加機能は使用できません。 APSchedulerとPython rqの組み合わせは有望でしたが、例はすべて同じファイルでclock.pyにスケジュールされていますが、私は単にすべての設定を自分の設定と結びつける方法がわかりません。前もって感謝します!

+1

あなたは複数のノードに分散されたWebアプリケーションを持っていて、6時間後にノードの1つで1つのタスク(関数を呼び出す)を実行したいのです...なぜ[Celery](http: //celery.readthedocs.org/en/latest/userguide/calling.html)何が必要ですか? –

+0

@PeterBrittain Herokuはノードとその環境を抽象化しました。それはdynoと呼ばれています。私の心配はノードについてではありません。私の懸念は、この環境内で完全に機能するジョブスケジューリングシステムを持つことができることであり、私は方法を考えることができません。おそらく私は3つのdynosを持つ必要があることを覚えています。 1つは私のアプリケーションを提供するためのもの、もう1つはスケジュールされたジョブを解析するスケジューラー用のものと、それらのタスクを実行するためのものです。そして、私の "views.py"では、スケジューラーdynoがそれを解析できるように、スケジュールされたジョブのそのデータベースに追加したいと思っています。さて、私はこの設定を準備したいと思います。 –

+0

私はセラーリーを稼働させたり、基本的に他のジョブスケジューラーと適切な文書を手に入れることができます。詳細は重要ではありません。私は、ジョブ/タスクのスケジューリングのこのシステムを持つより大きなイメージを探しています。 –

答えて

3

Herokuでは、DjangoアプリケーションをWeb Dynoで実行させることができます.Djangoアプリケーションは、アプリケーションの提供とタスクのスケジューリングを担当します。 たとえば、(コードを実行してテストしなかったことに注意してください):

after_hours.pyを作成します。これは、予定する予定の機能を持ちます(ワーカーでも同じソースコードを使用します)。あなたのviews.py

def after_6_hours(): 
     print('6 hours passed.') 

rq(タスクをスケジュールするために持っているとしてだけでrqがあなたの状況では十分ではないことに注意)とrq-schedulerを使用して:

from redis import Redis 
from rq_scheduler import Scheduler 
from datetime import timedelta 

from after_hours import after_6_hours 

def create_game(): 
    print('Game created') 

    scheduler = Scheduler(connection=Redis()) # Get a scheduler for the "default" queue 
    scheduler.enqueue_in(timedelta(hours=6), after_6_hours) #schedules the job to run 6 hours later. 

create_game()を呼び出すと、(after_6_hoursをスケジュールする必要があります)を実行します6時間後。
ヒント:Redis To Goアドオンを使用して、HerokuにRedisをプロビジョニングできます。

次のステップでは、1分ごとにRedisをポーリングしてその時点で実行するジョブがあるかどうかを調べ、それをキューに入れます(rqのワーカーがリッスンします)。今

Worker Dynoafter_hours.py

def after_6_hours(): 
    print('6 hours passed.') 
    #Better return something 

ファイルを作成し、別のファイルworker.py作成:

import os 

import redis 
from rq import Worker, Queue, Connection 

from after_hours import after_6_hours 

listen = ['high', 'default', 'low'] # while scheduling the task in views.py we sent it to default 

redis_url = os.getenv('REDISTOGO_URL', 'redis://localhost:6379') 

conn = redis.from_url(redis_url) 

if __name__ == '__main__': 
    with Connection(conn): 
     worker = Worker(map(Queue, listen)) 
     worker.work() 

とスケジュールされたタスクを実行する必要があり、このworker.py

python worker.py 

を実行します(この場合は)をWorker Dynoに追加します。 ここでのキーは、同じソースコード(この場合はafter_hours.py)を作業者にも提供することです。同じことがdocs

は、その労働者と作業発電シェアは正確に 同じソースコードを確認してくださいrqで強調されています。

もし役に立つとすれば、docsには異なるコードベースを扱うヒントがあります。ウェブプロセスは労働者で実行されているソースコード へのアクセス権を持っていない場合のために

(つまり、コードベースのXは、コードベースのYから遅れた機能 を呼び出します)、あなたは文字列として関数を渡すことができます参照、 もあります。

q = Queue('low', connection=redis_conn) 
q.enqueue('my_package.my_module.my_func', 3, 4) 

うまくいけばrq-schedulerすぎて、文字列の代わりに関数オブジェクトを渡すこの方法を尊重します。

このことを理解している限り、任意のモジュール/スケジューリングツール(Celery/RabbitMQ、APSchedulerなど)を使用できます。

関連する問題