2010年03月19日

GAEで不定期のイベント処理をするならTask Queue

決まった時刻や間隔で定期的に何か処理をしたい場合はCronを使用しますが、直前になるまで時刻が分からなかったり、突発的に発生するイベントの処理にはTask Queueを使います。

Task Queueはプログラム上から実行する時間を指定して登録できるCronに似たシステムです。CronがGETメソッドでパラメータ無しで呼び出されるのに対して、Task Queueは基本的にPOSTメソッドで呼び出され、パラメータも渡すことができます。

ちなみに、Task Queueはまだ実験的なシステムで現在はgoogle.appengine.api.labs.taskqueueというパスになっていますが、正式サービスに昇格する際にgoogle.appengine.api.taskqueueに変わる予定なので注意してください。

呼び出し元がユーザではなくGAEのシステムというだけで、それ以外は普通のCGIと同じなので基本的なことは説明するまでもないと思います。

タスク名とTombstonedTaskError

現在の仕様では、Task Queueはキューにタスクを追加する機能しかないので、あるタスクが既に登録されているか等の問い合わせができません。

タスクには名前を付けることができ、既にキュー内に同じ名前のタスクがある場合は、2つ目を登録しようとするとTaskAlreadyExistsErrorの例外が発生します。これで同じタスクの重複登録を防ぐことができます。

しかし、名前付きのタスクは無事に実行が完了してもしばらくの間は墓地に保管され、同名のタスクを再度登録しようとするとTombstonedTaskErrorという例外が発生してしまいます。この保管期間は明示されていませんが、24時間以上のようです。

TombstonedTaskErrorを避けつつ重複登録も防ぎたい場合は、タスク名に日付けと時刻のsufixを付けると良いようです。sufixの時間の粒度を調節することで、重複防止の期間もコントロールすることができます。例えば1日1回実行するタスクならば日付けまでで時刻は付けず、1時間に1回ならば分以下を省略、15分に1回ならば15分単位に切り捨てた時刻のようにします。

重複登録を防ぐ必要がなければ、タスク名は指定しない方がいいでしょう。

自動リトライ

cronもTask Queueも、例外が発生して処理が中断した場合は自動的に再実行されます。自分のコードに問題がなくてもDatastoreのアクセス等でエラーが発生することがありますが、そのような場合でも自動的にリトライしてくれます。エラー時に自前のリトライ処理をすると30秒制限が心配になりますが、自動リトライならば新たなセッションで開始されるので心配ありません。

GAE内のサービスだけを利用しているならばいくらリトライされても自己責任で済むのでいいのですが、外部のWebサービスにアクセスしている場合は自動リトライによってDoS攻撃まがいのことをしてしまうことがあるので注意が必要です。私も何度かtwitterやbit.lyに対して大量のアクセスをしてしまった経験があります。

自動リトライ自体はとても便利なので、私はcronやTask Queueではほとんどの例外を自分で処理せずにそのままエラーで終了させています。また、なるべく1つのジョブで複数のWebサービスにはアクセスしないようにしています。(2つ目のサービスへのアクセスでエラーが発生すると、リトライで再度1つ目のサービスにアクセスする必要があるので)

2010年03月19日 【プログラミング】 | コメント(1) |

この記事へのトラックバックURL


この記事へのトラックバック
この記事へのコメント

TwitterBotの場合は、自動リトライに任せるとTwitter側に思っていた以上に負担をかけてしまうので、自動リトライに任せるのはやめました。
Posted by 新坂 at 2010年07月28日

コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。