色聴者判定テスト > Google App Engine Task Queueの使い方

Google App Engine Task Queueの使い方

このページでは、Task Queueの簡単な使い方を解説します。

このページの内容で分からないところとかがあったら、@ts_3156 に何でも聞いてください。
「このコードのここの意味が分からない」とか、何でも大丈夫ですよ(^-^)

2011/02/08 追記
このページの内容は古くなったので、最新の情報で書き直しました。
最新情報はこちらです↓
Task Queueの最新情報!【設定ファイル例付き】

2010/12/15 18時頃追記
Task Queueの30秒制限が、バージョン1.4のGAE SDKからなくなったみたいです。
Cron、Task Queueのどちらとも、10分まで実行できるようになりました。
ソースはこちら↓
Google Appengine SDK 1.4.0 がリリースされました!

Google App EngineにはTask Queueと呼ばれる仕組みがあります。Cronのように定期的な プログラムの実行を行う仕組みです。Cronと何が違うの?と思うかもですが、Cronは決められた時間に実行されるものの、 Exceptionが起きたとしてもやり直してくれません。ですが、Task Queueは負荷が少ない時に 自動で再実行され、Exceptionが起きた時は自動的にやり直してくれます。
ですので、Cronで毎分1回の処理を行うと負荷が高すぎてまともに実行されないプログラムも、Task Queueを使えば 毎秒数回のペースで実行することができます。

こんなに便利なTask Queueですが、2010年10月の時点ではまだ日本語の資料が乏しいです。

Google App Engine Java Task Queueのページ(英語)
Task Queue Java API Overview

このページでは、Task Queueの使い方をサンプルコードをまじえてできる限り簡単に解説します。

Task Queueの設定ファイルの作成

Google App Engine公式のTask Queueの設定ファイルに関するページはこちらです。

Google App Engine JavaのTask Queue設定ファイルのページ(英語)
Java Task Queue Configuration

英語でわけが分からない人も多いと思うので、具体的なサンプルと共に解説します。

<queue-entries>
  <queue>
    <name>mail-queue</name>
    <rate>5/s</rate>
    <bucket-size>10</bucket-size>
  </queue>
  <queue>
    <name>background-processing</name>
    <rate>2000/d</rate>
  </queue>
</queue-entries>

上記のコードTask Queue設定ファイルの全てです。このコードを、queue.xmlというファイル名でwar/WEB-INFの中に保存してください。 これだけでTask Queueが使えるようになります。

◇nameタグ
nameタグはそのqueueの名前です。プログラムからTask Queueを実行する際に必要になります。自分が分かりやすい名前をつけましょう。 記号はハイフンしか使えないので注意してください。これとは別に、taskの名前も存在します。この設定ファイルの場合、mail-queueという queueが存在し、このqueueを何個か実行しようと思ったら、それぞれにtaskの名前を付けて実行することになります

◇rateタグ
rateタグはある時間内に実行できる最大の数です。5/sなら1秒間に5回、2000/dなら1日に2000回実行できます
たぶん、1日に~回という設定にすることは少ないと思います。こんな大雑把な数字では負荷の分散ができませんし。

◇bucket-sizeタグ
bucket-sizeタグは、専門的な言い方をするとトークンバケットのサイズのことです。
taskを1回実行するためにはトークンが1つ必要です。このトークンをためておける最大のサイズがbucket-sizeなわけです。
上記のコードのmail-queueを例に挙げて説明します。
全くtaskがない時、トークンは常に10個(bucket-sizeの値)たまっています。この時にtaskが一気に7個くると、 トークンを7個消費してこのtaskは全部即座に実行されます。
もしtaskが一気に12個くると、トークンを10個消費して10個のtaskが実行されます。それから1秒経過するとトークンが5個(rateの値)補充されます。 ここでやっと11個目と12個目のtaskが実行されるわけです。

Javaプログラム中でのTask Queueの使い方

使うクラスとAPIの一覧(英語)はこちらです。
Package com.google.appengine.api.labs.taskqueue
これだけを見せられても具体的な使い方が分からないと思うので具体的なコードを載せておきます。

importするのは以下のクラスです。

import com.google.appengine.api.labs.taskqueue.QueueFactory;
import com.google.appengine.api.labs.taskqueue.TaskOptions.Builder;
import com.google.appengine.api.labs.taskqueue.TaskOptions.Method;

次はJavaのコードです。
あるURLにアクセスするだけなら以下の1行だけです。

QueueFactory.getDefaultQueue().add(Builder.url("/printdata"));

getDefaultQueue()はデフォルトのqueueを作ります。queue.xmlに明示的に書いていなくてもデフォルトキューは作ることができます。
url("/printdata")はこのtaskに実行してもらうURLです。デフォルトではPOSTメソッドを使ってアクセスします。

QueueFactory.getQueue("mail-queue").add(Builder.url("/printdata").method(Method.GET));

今度はgetQueue("mail-queue")を使いました。こうすることで、mail-queueのrateタグ、bucket-sizeタグの値が利用されます。
method(Method.GET)をつけたことでGETメソッドを使ってアクセスします。ここをPOSTに変えると、POSTメソッドでアクセスするようになります。

QueueFactory.getQueue("mail-queue").add(Builder.url("/printdata").param("name", "yamada").param("id", 1234).method(Method.POST));

param("name", "yamada")、param("id", 1234)を付けました。これはPOSTメソッドで渡すパラメータの値です。無制限に連結できるかは知りませんが、 5、6個くらいだったら普通に大丈夫だと思います。

QueueFactory.getQueue("mail-queue").add(Builder.url("/printdata").taskName("20101004-2004-create").method(Method.GET));

taskName("20101004-2004-create")を付けました。これにより、mail-queueというqueueの、20101004-2004-createというtaskが作られます。 taskの名前は重複することができません。実行が終わった後も、1週間くらいは同じ名前を付けられないようです。なので、taskの作成日時 などを名前に入れて重複しないよう管理しましょう。記号はハイフンしか使えないので注意してください。
taskName()を省略すると、Long型の値が勝手に付けられます。
queueの名前、taskの名前、再実行された回数はHTTPヘッダの中に埋め込まれます。

「X-AppEngine-QueueName」queueの名前。この場合mail-queue
「X-AppEngine-TaskName」taskの名前。この場合は20101004-2004-create
「X-AppEngine-TaskRetryCount」このtaskが再実行された回数。最初の1回目の場合は0

QueueFactory.getQueue("mail-queue").add(Builder.url("/printdata").countdownMillis(10000));

最初の1回をある一定時間後に実行したい場合は、countdownMillis(10000)を付けます。この場合は、10000ミリ秒(10秒)後に実行されます。
2回目以降の実行タイミングは、Google App Engine側で勝手に決められます。
経験則的には、最初のやり直しは約5秒後、次のやり直しは約10秒後、次は約30秒後、次は約60秒後… のように段階的に長くなるようです。また、負荷が少ない時を見計らって実行してくれるようです
Exceptionがでたらやり直してくれるのですが、catchしてしまうと正常に実行されたとみなされるので再実行されません。 Exceptionはcatchせずに無視しましょう。

QueueFactory.getQueue("mail-queue").add(Builder.url("/printdata").header("original-header", "test"));

header("original-header", "test")を使えばヘッダの値を追加することができます。

2010年10月の時点ではTask Queueにも30秒制限があるので注意しましょう。将来的にはなくなるとか書いてありますが、少なくとも現時点では存在します。

2010年10月5日追記
Task Queueの30秒制限が段階的になくなっているっぽい??です。
Google App EngineのLogに、34224msのように30秒を超えるものがたまにでてきます。

2010/12/15 18時頃追記
Task Queueの30秒制限が、バージョン1.4のGAE SDKからなくなったみたいです。
Cron、Task Queueのどちらとも、10分まで実行できるようになりました。
ソースはこちら↓
Google Appengine SDK 1.4.0 がリリースされました!

このページを見てる方がTask Queueを使う場合って、 順番に実行する必要のある大きなプログラムを小さいプログラムに分割して実行する場合とかだと思います。 そういう時は、それぞれのtaskの中で、実行が正常に完了したら新しいtaskを追加、時間切れになりそうだったら new RuntimeException()を実行、とかするのが現実的だと思います。

このように、自分の実行が終わったら新しいtaskを追加するような仕組みを工夫すれば、長時間が必要な処理もうまくやりくりできるはずです。

このページの内容で分からないところとかがあったら、@ts_3156 に何でも聞いてください。
「このコードのここの意味が分からない」とか、何でも大丈夫ですよ(^-^)

色聴判定テスト一覧
テストはどれも10分ほどで終わります
推奨環境
・Internet Explorer7以降
・Firefox3以降
判定テストについて
これまでに 1541人 がテストを受けました
09/12/28~12/02/02
更新情報
・12/10/14
twitterの埋め込み方法を更新しました
・12/01/11
共感覚面白ニュースを更新しました
・11/11/03
共感覚面白ニュースを更新しました
・11/04/03
筑波大学新入生向け情報を書きました
・11/03/04
Twitter4j逆引きリファレンス【使い方 やりたいことから見つける】を書きました
もっと見る
知りたい情報募集中
知りたい情報は見つかりましたか? 見つからなかったならご連絡ください。 詳しく調べて、ネットでは見つからないような良質で科学的な情報を掲載いたします。

研究協力者も募集中です!
お問い合わせはこちら