Google App Engine SDK 1.4.0 がリリースされました!
Google App Engine1.4.0がリリースされました!!このリリースはかなりでかい!!チャンネルAPI,”Always On”(リザーブインスタンス)、タスクキューの正式リリース、スタートアップリクエスト、バックグラウンド処理の改善などなど、
チャンネルAPI
まずは、一番重要なチャンネルAPI。チャンネルAPIでクライアントブラウザーにプッシュすることができるようになります。内部的には、Google TalkのXMPPインフラを使っているらしくて、それでスケールアウトしてくれます。チャンネルAPIは2つの部分がに分けています。サーバー再度のチャンネルAPIとチャンネルAPIのJavaScriptライブラリ。
チャンネルAPIはサーバー側から、クライアントの通信に使います。クライアントからサーバーへの通信は今までどおりのPOSTがGET HTTPリクエスト。
サーバー側
まずは、チャンネルのIDをクライアントに渡す。クライアントはそのIDを使って、チャンネルに接続する。
channel.create_channel()に渡すuserは、ユーザーだけじゃなくて、内部的に文字列にするので、create_channel()に渡すデータは単の文字列でも大丈夫です。
from google.appengine.ext import webapp
from google.appengine.api import channel
from django.template.loader import render_to_string
class MyHandler(BaseHandler):
def get(self):
user = users.get_current_user()
# ユーザーのチャンネルを作る
# create_channel に渡すデータは単の文字列でも大丈夫
id = channel.create_channel(user)
return self.response.out.write(
render_to_string(
"index.html",
{"channel_id": id},
)
)
クライアント側のJavaScriptはチャンネルに接続
var channel = new goog.appengine.Channel("{{ channel_id }}");
var socket = channel.open();
socket.onopen = function () {
window.setTimeout(function () {
alert("Connected!");
}, 100);
};
// メッセージのハンドラーを登録
socket.onmessage = function (evt) {
// テキストを受けているけど、JSONがおすすめ
// var o = JSON.parse(evt.data);
alert(evt.data);
// do something
};
サーバーからクライアントにメッセージを送る
from google.appengine.api import channel
from google.appengine.api import users
class AjaxHandler(BaseHandler):
def get(self):
user = users.get_current_user()
# メッセージをクライアントに渡す。
# クライアントが接続している状態が不要
# 誰も接続してない場合は何もしない
# ここでテキストデータを送るけど、JSONがおすすめです
channel.send_message(user, "Hello World!!")
Channel API のドキュメント:
http://code.google.com/intl/ja/appengine/docs/python/channel/overview.html
Always On
今までは、リクエストが少ない場合は、App Engineのサーバーインスタンスがすべて落とされるので、リクエストがその状態で来た時、かなりスピンアップ(サーバーインスタンスの起動)に時間かかってしまいました。”Always On”という機能を使うと3つのインスタンスを保持してくれます。有料ですが、かなりスピンアップに困っている人に好調的だね。
Note: “Always On”はアクセスがあんまりこない時のみに効果があるので、自分のアプリは常にトラフィック量が高い場合、最低3つのインスタンスを保持してもしょうがないです。3つまで下がってないからです。
スタートアップリクエスト
この機能もスピンアップにいいのですが、効果がちょっと違うので、説明します。今まで、リクエストが増えて、スケールアウト(新しいインスタンスの起動)が必要な場合、あるリクエストが新しいインスタンスに割り当てると、インスタンスがロードに時間かかったり、DeadlineExceededErrorが出たりしました。
スタートアップリクエスト機能は、スケールアウトが必要な場合、ユーザーからのリクエストを割り当てる前に、スタートアップリクエストをインスタンスに投げる。このリクエストで必要なモジュールを未然にロードできるようになります。それで、最初のユーザーリクエストが来たら、より速く返せるようになります。
つまり、スタートアップリクエストがスケールアウトする時に効果があるので、インスタンスがいくらでもあっても効果的です。
使うには、まずはメールみたいに、inbound_servicesをapp.yamlに設定します。
inbound_services:
- warmup
スタートアップリクエストが/_ah/warmupのURLに来るので、スタートアップリクエストを受けとるURLをapp.yamlに設定する。
- url: /_ah/warmup.*
script: warmup.py
warmup.pyの中に、必要そうなモジュールをインポートする。
# ロードが重いモジュールを未然にロードする
import mybigmodule
import myothermodule
def main():
print "Content-type: text/plain"
print "OK"
タスクキュー正式リリース
今まで、App EngineのタスクキューはBetaでgoogle.appengine.api.labs.taskqueueに入っていたけど、labsから卒業するので、google.appengine.api.taskqueueに移動される。タスクキューのデータもデータのクオータに含まれるようになります。データクオータにひっかかるので、ヘビーに使っている人たちはちょっと大変かもしれない。
cron/タスクキューの改善
cronとタスクキューの時間制限は今まで、30秒でしたが、10分になります。ですが、長く実行しているcronジョブ・タスクは認識され、別インフラに移動されて、スループット(実行頻度)が落ちるので、速くて小さいタスクが良好だと言われる。
Metadata クエリー
App Engineデータストアのメタデータ、Namespace,Kind,Propertyをクエリすることができるようになりました。メタデータのモデルクラスはgoogle.appengine.ext.db.metadataモジュールに入っています。
Kindインスタンスが持っているPropertyの親になるので、あるKindのPropertyを取得するには、ancestor()クエリができます。
from google.appengine.ext.db.metadata import Namespace, Kind, Property
for namespace in Namespace.all():
print namespace.namespace_name
for kind in Kind.all():
print kind.kind_name
for property in Property.all().ancestor(kind):
print " %s" % property.property_name
ダウンロード
ダウンロードページではまだ出てないみたいですが、code.google.comのプロジェクトの以下のURLからダウンロードできます。
- Python:
google_appengine_1.4.0.zip - Java:
appengine-java-sdk-1.4.0.zip - リリースノート