#ajn3.lt.marblejenka
DESCRIPTION
lightning talk at appengine java night, in japanTRANSCRIPT
![Page 1: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/1.jpg)
makeSyncCallで
いろいろ試してみた#ajn3ライトニングトーク
![Page 2: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/2.jpg)
自己紹介
![Page 3: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/3.jpg)
@marblejenka
![Page 4: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/4.jpg)
•普段のお仕事
• java/c++な金融系業務システム開発
• appengineとの関わり
• なんかいろいろ楽しそうだったからはじめてみた
• balmysundaycandyというmakeSyncCallしやすくするライブラリをつくり中
![Page 5: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/5.jpg)
makeSyncCallとは!
![Page 6: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/6.jpg)
makeSyncCall• appengineにおけるサービス呼び出しを実行する
(UserServiceの一部を除く)
• サービス呼び出しはprotocol bufferでシリアライズして通信、それを実現しているメソッド
• stubの実装はproduction側で管理
• 個人的にはEnvironment上書きとは別物と理解すべきと思ってます
• makeSyncCallによるサービス呼び出しを、通称more low level apiと呼びます
![Page 7: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/7.jpg)
Why more low level?(today’s goal)
![Page 8: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/8.jpg)
• low levelより速い?
•いろいろなapiを経由するより直で触った方が高速では!?
•できないことができるかも?
•公開されていないapiを触れる!?
• appengineの勉強になる?
• JDOに対するlow level apiなのか!?
![Page 9: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/9.jpg)
more low levelは高速か?
![Page 10: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/10.jpg)
検証内容• low level vs more low levelでの比較
• 交互に1件のエンティティをget
• 1リクエストで50回実行、20回繰り返し各1000サンプルを採取
• ※datastoreには対象kindを10000件程度putした状態にしてあるが、前評判通りstoreされているデータ量にパフォーマンスが依存しないのは確認済み
![Page 11: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/11.jpg)
0
75
150
225
300
1 3 5 7 9 11 14 17 20 23 26 29 32 35 38 41 44 47 50
low level vs more low level
more low levellow level
結果の分布:横軸に所要時間ms、縦軸に発生回数ほとんど差異はない(むしろ20ms近傍が気になる)
![Page 12: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/12.jpg)
more low levelはいろいろできる?
![Page 13: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/13.jpg)
datastore#count•queryに対する件数が取れる
com.google.apphosting.api.DatastorePb.Query query = new Query(); query.setApp(APPID); query.setKind(KIND_NAME); Integer64Proto countproto = DatastoreOperations.COUNT.call(query);
• ※以降、ピンクをprotocol bufferオブジェクト、青字部分はぼくのライブラリを使っている箇所として記載しています
![Page 14: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/14.jpg)
datastore#GetIndices• composite indexの情報がとれる
StringProto request = new StringProto(); request.setValue(APPID); CompositeIndices response = DatastoreOperations.GET_INDICES.call(request); ---------------------------- state:2 entity_type: "TEST" ancestor: false Property { name: "hoge" direction: 1 } Property { name: "hige" direction: 1 }
![Page 15: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/15.jpg)
datastore#getScheme
• スキーマ情報がとれる(が、productionでは動作せず。。)
GetSchemaRequest getSchemaRequest = new GetSchemaRequest(); getSchemaRequest.setApp(appid); Schema schema = DatastoreOperations.GET_SCHEMA.call(getSchemaRequest);
![Page 16: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/16.jpg)
datastore#getScheme property < name: "name" value < stringValue: "none" > multiple: false >>more_results: false
※ entity_groupは、more low levelでgetしたときも取得できる
kind < key < app: "balmysundaycandy" path < Element { type: "TEST" } > > entity_group <
> property < name: "age" value < stringValue: "none" > multiple: false >
![Page 17: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/17.jpg)
まだまだ謎も多い
•DatastoreOperations.ADD_ACTION
•DatastoreOperations.NEXT
•DatastoreOperations.EXPLAIN
•DatastoreOperations.DELETE_CURSOR
![Page 18: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/18.jpg)
more low levelは勉強になる?
![Page 19: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/19.jpg)
こういうことがわかる• 実現可能なアーキテクチャの(おそらく最小粒度の)素材に何が使えるかわかる
• appengineには43のサービス呼び出しが定義されており、その組み合わせでapiが実現されている
• 先に紹介したような、low level apiでも提供されていないものもある
• 将来実現されるかもしれないapiを先取り!?
• サービス呼び出しのなかでも比較的複雑なdatastoreの仕組みが垣間みれる
• トランザクションの開始、rollback、commitもそれぞれ一つのサービス呼び出しとして実現されている
![Page 20: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/20.jpg)
ところで
![Page 21: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/21.jpg)
appengine 1.2.8prerelease!!
![Page 22: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/22.jpg)
makeAsyncCall
![Page 23: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/23.jpg)
非同期なサービス呼び出し!!
Future<QueryResult> future = DatastoreOperations.RUN_QUERY. callAsync(query, apiConfig);long asyncCallEnd = System.currentTimeMillis();int notDoneCount = 0;while (!future.isDone()) { ++notDoneCount;}long callEnd = System.currentTimeMillis();
![Page 24: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/24.jpg)
makeAsyncCall
![Page 25: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/25.jpg)
TQじゃだめなのか?
![Page 26: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/26.jpg)
• taskqueue
• 例外発生時の自動再実行&冪等性
• レスポンスは今のところ返せない
• more low level async
• 単純なサービス呼び出しを非同期化
• deadline決めうち、30秒を超えない範囲の並列化 or non blocking
• レスポンスは返せるが、並列化できる処理に限る
![Page 27: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/27.jpg)
wrap up!
![Page 28: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/28.jpg)
• low levelより速い?
•そんなことはなかった。
•できないことができるかも?
•触れないこともないが、実開発と言うよりはツール向けの機能という印象。謎もある。
• appengineの勉強になる?
• なります!まぁこころの持ちようかも?
![Page 29: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/29.jpg)
Async時代はmore low levelが制する!?
![Page 30: #ajn3.lt.marblejenka](https://reader035.vdocuments.site/reader035/viewer/2022081403/55621e4dd8b42ac6588b4743/html5/thumbnails/30.jpg)
Thank You!!