バックグラウンド処理とタスクキュー

□未翻訳

□翻訳中

□翻訳完了(細田謙二)

■レビュー(中垣健志)

バックグラウンド処理とタスクキュー

クーロンは一定の時間間隔で実行するタスクには便利ですが、バックグラウンドタスクを実行するための解決策として常に最良というわけではありません。このため、web2pyはどのpythonプログラムもコントローラのように実行する機能を提供しています:

While cron is useful to run tasks at regular time intervals it is not always the best solution to run a background task. For this purpose web2py provides the ability to run any python script as it were insider a controller:

1.

python web2py.py -S app -M -N -R applications/app/private/myscript.py -A a b c

こ こで、-S appは"myscript.py"を"app"として実行することをweb2pyに知らせます。-Mはモデルを実行することを知らせ、-Nはクーロンを 動作させないことを知らせます。-A a b cはオプション的なコマンドラインの引数sys.args=['a','b','c']を"myscript.py"に渡します。

where -S app tells web2py to run "myscript.py" as "app", -M tells web2py to execute models, -N tells web2py not to run cron, and -A a b c passes optional command line argumentssys.args=['a','b','c'] to "myscript.py".

典型的なテスト事例は、キューを処理することです。

A typical test case consists of processing a queue.

次のようなモデルを考えます

Consider this model

1.

2.

3.

4.

5.

db.define_table('queue',

Field('status'),

Field('email'),

Field('subject'),

Field('message'))

また、次のように送られるメッセージをキューに入れるアプリケーションを考えます

and an application that enqueues messages to be send by

1.

2.

3.

4.

db.queue.insert(status='pending',

email='you@example.com',

subject='test',

message='test')

メールを送るバックグラウンド処理のスクリプトは次のようにします

The background processing script that sends the emails could be

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

# in file myscript.py

import time

while True:

rows = db(db.queue.status=='pending').select()

for row in rows:

if mail.send(to=row.email,

subject=row.subject,

message=row.message):

row.update_record(status='sent')

else:

row.update_record(status='failed')

db.commit()

time.sleep(60) # check every minute

なお、mailオブジェクトは雛形となるアプリのdb.pyファイルにて定義されたものですが、-Mオプションがあるため、ここで利用できることに注意してください。mailはdb.pyにてきちんと動作するように設定する必要があります。ただしまた、どのような変更でもすぐにコミットすることは重要です。他の並行して走るプロセスに対してデータベースをロックしないようにするためです。

Notice that the mail object is defined in the db.py file in the scaffolding app, but because of the-M option it is visible here. It may need to be configured in db.py to work properly. Also notice that it is important to commit any change as soon as possible in order not to lock the database to other concurrent processes.

このタイプのバックグラウンド処理は、クーロンで実行するべきではありません(@rebootのクーロン以外は)。なぜなら、同時に実行されるインスタンスが1つしかないことを保証する必要があるからです。クーロンでは、プロセスがクーロンのイテレーション1を開始し、クーロンのイテレーション2によって終了できない可能性があり、その場合、クーロンはさらにそれを開始し、開始し、というようになって、メールサーバを妨害します。

This type of background process should not be executed via cron (except perhaps for cron @reboot) because you need to be sure that no more than one instance is running at the same time. With cron it is possible that a process starts at cron iteration 1 and is not completed by cron iteration 2, so cron starts it again, and again, and again - thus jamming the mail server.