26
AppEngine 1.4.0 SDK ソースコードから見る実行環境 bpstudy #40 (2010.12.21) @tagomoris

Bpstudy20101221

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Bpstudy20101221

AppEngine 1.4.0 SDKソースコードから見る実行環境

bpstudy #40 (2010.12.21)@tagomoris

Page 2: Bpstudy20101221

tagomorisTAGOMORI Satoshi / 田籠 聡

Twitter: @tagomorisE-mail: [email protected]

Blog: http://d.hatena.ne.jp/tagomoris/

GAETestBase (python), simpleoauth-gae (python),

Stratum(ruby), PassengerMonitor(ruby), ... GlassDolphinsource code viewer for iPad/iPhone

Page 3: Bpstudy20101221
Page 4: Bpstudy20101221

本日の話AppEngine Python SDKのコードの話とか

空白とか

AppEngine 実行環境の構造とか

remote_api の話とか

ツッコミは適宜どうぞ

Page 5: Bpstudy20101221

SDK読む?

ドキュメント読む?

Page 6: Bpstudy20101221

AppEngineのコードの特徴• Python, Javaで実装がかなり似ている

• 内部APIのコール名まで共通点が多い

• 基本的にバックエンドへのRPCが透けて見える

• Service側は全部共通だし

• 各サービスの制約や最適化方法も多分共通でしょう

• MultiQueryとかー、batch putとかー

Page 7: Bpstudy20101221

GoogleのPythonコード• 基本的にすごく綺麗で読みやすい

• メソッド名から内容がちゃんと分かるのはスゴい

• ただし処理がすごく細切れ

• 数行ですぐ他所に処理が飛ぶ

• 同じ名前のメソッドがあちこちのモジュールにある

• Google Python Style Guide

• http://google-styleguide.googlecode.com/svn/trunk/pyguide.html

• http://works.surgo.jp/translation/pyguide.html (和訳 rev 2.15)

Page 8: Bpstudy20101221

Google流モジュール取扱い• import方法

import google.appengine.ext.db.*

Model.get(...)

from google.appengine.ext import db

db.Model.get(...)

Page 9: Bpstudy20101221

Google流モジュール取扱い•関数定義の再代入の多用

# google/appengine/api/datastore.py

def IsInTransaction():

....

_CurrentTransactionKey = IsInTransaction

# google/appengine/ext/db/__init__.py

run_in_transaction = datastore.RunInTransaction

RunInTransaction = run_in_transaction

Page 10: Bpstudy20101221

空白

Page 11: Bpstudy20101221

一番楽しいのは「空白の行」

google/appengine/api/appinfo.py (...260, ...636)google/appengine/api/datastore_types.py(1129, ...1584)

google/appengine/cron/GrocLexer.py, GrocParser.pygoogle/appengine/datastore/datastore_sqlite_stub.py (...88)

google/appengie/ext/db/__init__.py (...1569)google/appengine/runtime/apiproxy.py (...85)

そのほかあちこち

Page 12: Bpstudy20101221

合言葉は

MakeSyncCall

Page 13: Bpstudy20101221

from google.appengine.ext import webappfrom google.appengine.ext.webapp.util import run_wsgi_appfrom google.appengine.ext import db

class Tekitou(db.Model): pass

class MainPage(webapp.RequestHandler): def get(self): Tekitou.get_by_id(100) self.response.out.write("<html><body><p>tagomoris test page...</p></body></html>")

application = webapp.WSGIApplication([('/', MainPage), #('/msc_datastore', DatastoreMakeSyncCall), ], debug=True)

def main(): run_wsgi_app(application)

if __name__ == '__main__': main()

適当に書いたハンドラ

Page 14: Bpstudy20101221

Traceback (most recent call last): File ".../google/appengine/ext/webapp/__init__.py", line 515, in __call__ handler.get(*groups) File "/Users/tagomoris/Documents/tagomoris-test/main.py", line 14, in get Tekitou.get_by_id(100) File ".../google/appengine/ext/db/__init__.py", line 1115, in get_by_id return get(keys[0], config=config) File ".../google/appengine/ext/db/__init__.py", line 1320, in get entities = datastore.Get(keys, config=config) File ".../google/appengine/api/datastore.py", line 443, in Get return _GetConnection().async_get(config, keys, extra_hook).get_result() File ".../google/appengine/datastore/datastore_rpc.py", line 548, in get_result self.check_success() File ".../google/appengine/datastore/datastore_rpc.py", line 519, in check_success rpc.check_success() File ".../google/appengine/api/apiproxy_stub_map.py", line 501, in check_success self.__rpc.CheckSuccess() File ".../google/appengine/api/apiproxy_rpc.py", line 149, in _WaitImpl self.request, self.response) File ".../google/appengine/api/datastore_file_stub.py", line 618, in MakeSyncCall response) File ".../google/appengine/api/apiproxy_stub.py", line 80, in MakeSyncCall raise RuntimeError, "just before call method %s" % ('_Dynamic_' + call)

RPC実行直前で例外を投げた状態

Page 15: Bpstudy20101221

MakeSyncCallの壁 ApiProxyStubMap

Taskqueue

Memcache

Users

ApiProxyStub

UrlFetch

ext.db

ユーザアプリケーションのコード

ApiProxyStubMap

Datastore

ServiceStubDatastoreFileStub DatastoreSqliteStub CapabilityStub

ProtocolBuffer

各種RPC

Page 16: Bpstudy20101221

MakeSyncCallの壁 ApiProxyStubMap

Taskqueue

Memcache

Users

ApiProxyStub

UrlFetch

ext.db

ユーザアプリケーションのコード

ApiProxyStubMap

Datastore

ServiceStubDatastoreFileStub DatastoreSqliteStub CapabilityStub

ProtocolBuffer

各種RPC

このへん読みたい

Page 17: Bpstudy20101221

大事なこと ふたつ

•どこを読むべきかを意識しながら

•次の行き先を確認しながら

Page 18: Bpstudy20101221

では読んでみよう!

1.google/appengine/ext/db/__init__.py (1115, get_by_id)2.google/appengine/ext/db/__init__.py (1320, get)3.google/appengine/api/datastore.py (443, Get)4.google/appengine/datastore/datastore_rpc.py (548, get_result)5.google/appengine/datastore/datastore_rpc.py (519, check_success)6.google/appengine/api/apiproxy_stub_map.py (501, check_success)7.google/appengine/api/apiproxy_rpc.py (149, _WaitImpl)8.google/appengine/api/datastore_file_stub.py (618, MakeSyncCall)9.google/appengine/api/apiproxy_stub.py (80, MakeSyncCall)

だいたいこんな順番で潜っていくよー

番外: google/appengine/runtime/apiproxy.py

Page 19: Bpstudy20101221

remote_api• 開発環境のStubを全部 RemoteStub に置き換える

• Datastoreだけ RemoteDatastoreStub

• RemoteStub が全てのRPC(MakeSyncCall)を受け取る

• 処理するフリをしてappspotにそのままHTTP RPCで投げる

• appspotでRemoteApi専用のハンドラが受け取る

• そのまま本物のApiProxyStubに投げて処理させる

Page 20: Bpstudy20101221

remote_apiの用途

• remote_api_shell.py で実験やメンテナンス

• GAETestBase

• URLFetchService 動作確認とか (to Twitter)

Page 21: Bpstudy20101221

remote_apiのRPC構造

remote_api handler

ApiProxyStubMap

user application

ApiProxyStubMap

Service

ServiceStubRemoteStub

remote_api_shell

HTTP RPC

Page 22: Bpstudy20101221

remote_apiのRPC構造

remote_api handler

ApiProxyStubMap

user application

ApiProxyStubMap

Service

ServiceStubRemoteStub

remote_api_shell

MakeSyncCall

MakeSyncCall

HTTP RPC

Page 23: Bpstudy20101221

remote_apiのRPC構造

remote_api handler

ApiProxyStubMap

user application

ApiProxyStubMap

Service

ServiceStubRemoteStub

remote_api_shell

MakeSyncCall

MakeSyncCall

HTTP RPC

Page 24: Bpstudy20101221

何が言いたかったか

AppEngineはSDKのコードを読むといろいろわかる

AppEngineはコードさえ書けばあれこれできる

コードを書かないと何もできない

Page 25: Bpstudy20101221

わからないことがあったコードを読もう。できないことがあったらコードを書いて解決しよう。

問題と解決をみんなでシェアしよう。あなたの問題は、きっとみんなの問題だ。

Page 26: Bpstudy20101221

ありがとうございました