Google Cloud Platform Advent Calendar 2014の4日目担当のshin1ogawaです。
最近はGoogle App Engine(以降GAEと表記)でやれば構築・メンテナンス・ランニングコストが1/10以下になるであろう案件を、あえてGCEで構築するということに関わっていて、GAEの素晴らしさをますます再認識しています。GAEでササッとやれば楽なのに…
Task Queue REST API とは?
Google App Engine(以降GAEと表記)には Task Queueという機能があります。処理(タスク)をキューに放り込んでおけば、処理が成功するまではGAEが何度でもリトライしてくれる便利な機能です。このTask Queueには、キューに追加した処理がGAEにより自動実行されない Pull Queue という種類があり、これを使うとGAEではない外部のプラットフォームからキューに入っている処理を引き出す事ができます。このPull Queue内の処理を操作するAPIがTask Queue REST APIです。Discovery based APIに準拠しているので、他のGoogle APIを使ったことがある方は自然に使えると思いますが、設定にはまりどころがあるので、主に設定方法について説明します。
例えばGAEでは実装できない、動画やPDFを処理する機能を提供するために、アプリケーションはGAE上で運用するが一部機能だけGoogle Compute Engine(以降GCEと表記)やAWS上のインスタンスで処理する、といった時に使用できます。
なお、GAEではQueueに入れる「処理(タスク)」とは、「アプリケーションに対するHTTPリクエスト」となります。処理のためのパラメータは、リクエストパラメータとして設定することになります。例えば特定のファイル(GAEの場合はGoogle Cloud Storageに配置することが多いですね)を取得して何か加工するといった場合は、キューには「ファイルのパス」をパラメータとして設定したHTTPリクエストを追加することになります。
この記事では外部環境からGAEのPull Queue内のタスクを利用する方法を説明します。
Pull Queue を作成する
Pull Queueを作るだけであれば、通常のqueue定義に<mode>pull</mode>
を追加するだけです。
<queue-entries>
<queue>
<name>normalqueue</name> <!-- 自動実行される通常のQueue(Push Queue) -->
<rate>10/s</rate>
</queue>
<queue>
<name>pullqueue</name>
<mode>pull</mode> <!-- 自動実行されないPull Queue -->
</queue>
</queue-entries>
Pull Queue にタスクを追加する
通常のTask Queueとの違いは大きくは2点で、「HTTPリクエストのメソッドとして"PULL"という特別な値を設定する」「自動実行される時のハンドル先(URL)を設定しない」という点です。
例えばJavaなら次のようになります。
QueueFactory.getQueue("pullqueue").add(
TaskOptions.Builder.withMethod(TaskOptions.Method.PULL).payload("parameters...");
GAE上のアプリケーションからPull Queueに処理を追加する方法は通常のTask Queueの使い方とほとんど同じで簡単ですので、次の公式リファレンスを参照してください。
- https://cloud.google.com/appengine/docs/java/taskqueue/overview-pull
- https://cloud.google.com/appengine/docs/python/taskqueue/overview-pull
- https://cloud.google.com/appengine/docs/go/taskqueue/overview-pull
Task Queue REST API のための準備
- Developer Consoleにプロジェクトが必要ですが、GAEアプリケーションがすでにある場合は、それと同じプロジェクトを使うとよいです(GAEアプリケーションとは別にプロジェクトを作っても問題ありません)。
- Developer Consoleのプロジェクトで、OAuth2認可のためのClient IDを発行します。詳しくはこの記事など、Google APIのOAuth2を使う記事を参考にしてください。
- 発行したClient ID, Client Secret, Project IDを使って、スコープ:
https://www.googleapis.com/auth/taskqueue
に対する認可を行い、アクセストークン(1時間で期限が切れます)かリフレッシュトークンを取得しておきます。これについても上記の記事などが参考になります。
まだ設定が足りない!
さて、ここまでの手順で、Task Queue REST APIに必要であろう、Client IDが発行済で、それを使ったアクセストークン(リフレッシュトークン)も取得できた。後はAPI Explorerや自身のプログラムからPull Queueを操作できるね…と思ってしまいます。特に、普段からGoogle APIに慣れている人はそう思いがちです。私は何回もハマってます。
上記の手順では設定が足りません。GAEのPull Queueの設定に、外部から「アクセス可能なユーザ」の設定をメールアドレス単位で設定する必要があるのです!なにこれいびつ、気持ち悪!
<queue-entries>
<queue>
<name>pullqueue</name>
<mode>pull</mode> <!-- 自動実行されないPull Queue -->
<acl>
<user-email>shin1ogawa@example.com</user-email>
<writer-email>shinichi.ogawa@example.com</writer-email>
</acl>
</queue>
</queue-entries>
wrirer-email
と user-email
なので、書き込み可能な権限と、読み取り可能な権限と思いきや、そうでもありません。
user-email
では list, get, delete, lease, update
といった操作が可能です。insert
だけは writer-email
にする必要があります。
もちろん、アクセストークン(リフレッシュトークン)は、ここで指定されたアカウントで認可して取得する必要があります。
ここまでくれば、今度こそ通常のDiscovery basedなGoogle APIと完全に同じように使えます。ε-(´∀`*)
主な手順は次のようになります。
- 処理をキューから
lease
する(期限を指定する) - 完了した処理をキューから
delete
する(deleteまでに処理期限が切れたら、自動的にQueueに戻される)
公式リファレンスに複数の言語に対応したライブラリが記載されていますので、それらを使うと便利です。
まとめ
Task Queu REST APIは他のGoogle APIと同じ使い方のはずなのに、Developer Consoleのプロジェクトに設定されたアカウント類が適用されないという、ビミョーな注意点があります。そこだけ注意すれば良いですが、気持ち悪い。
GAE の Pull Queueの設定にメールアドレス単位のACLを追加しろ
この一言で十分でしたが、今年に入ってから二回ハマり、ムダに時間を消費した経験から記事としました。