SiNBLOG

140文字に入らないことを、極稀に書くBlog

Slim3 Source Code Reading #2 に参加してきた!

Slim3 Source Code Reading #2 に参加してきました!
#1にも参加していましたが、学習した内容をまとめる方法を考えていたら、#2に・・・。

考えている残骸がこちら・・・。
http://dl.dropbox.com/u/15506977/document/slim3codereading/html/index.html

#1では、FrontControllerを読んで、requestが来た時のルーティングの処理を学習しました。


#2では、appengineのキモ、Datastoreについです。
とりあえず、Datastore#put()周りから読み進んで行きました。
Datastore関係のメソッドは、同期と非同期があるようで、大抵同じようなメソッドが2種類あります。
put()を例にすると、以下のような感じ。


public static Key put(Entity entity) //同期
public static Future putAsync(Entity entity)

ただ、中では同期側がjava.util.concurrent.Futureを介して、非同期側を呼んでいるようです。


とりあえず、google api を呼び出すところまで潜水して、浮かんだ疑問点は以下の通り。

  1. ModelMeta#assignKeyToModelRefIfNecessary(AsyncDatastoreService ds, Object model)の中身が空
  2. ModelMeta#prePut(Object model)の中身が空
  3. ModelMeta#postGet(Object model)の中身が空
  4. DatastoreTimeoutException発生時に、リトライを行うはずだが、その処理が見当たらない

1に関してはメソッド名から推測するに、リレーションを貼る場合に生成される?
Unidirectional One-to-One Relationships - Slim3
リレーションを貼っているソースが手元に無かったので、ちょっとテストコードを作ってみよう。


2,3に関しては、Datastoreに格納する値と、javaのclassとの変換処理が入ったりするのではないか?
という憶測は出たのだが、確認は出来ず。


4に関しては色々と調べてみたが、分からなかった。
元々の話はSlim3本に出てくる以下の内容。

Amazon CAPTCHA


5-5-5 データストア操作のタイムアウト(P109)
Google App Engineのデータストアに対する操作は、保存・取得・削除・idの確保などのすべての操作に関して「com.google.appengine.api.datastore.DatastoreTimeoutException]という例外が投げられる可能性があります。

この記述に対して、LowLevelAPIを使っていく場合、リトライ処理をする必要があるとサンプルソースと共にやり方が載っています。

それに対して、


6-6-2 Put、Get、Delete(P214)
Slim3では全ての操作についてこのリトライ処理を実行してくれますので、Slim3を使って開発する場合はDatastoreTimeoutExceptionの心配がありません。

とあります。

また、こちらのBlogでも関係するお話が出ていました。
http://d.hatena.ne.jp/bufferings/20100609/1276110414


しかし、どちらも1年以上前の話なので、頻繁にUpdateがあるGAEでは、もう過去の話になってしまっているのかも・・・。
しかも、帰宅後にslim3リポジトリを遡っていると、以下のソースを見つけました。


135 public static Transaction beginTransaction() {
136 DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
137 DatastoreTimeoutException dte = null;
138 long wait = INITIAL_WAIT_MS;
139 for (int i = 0; i < MAX_RETRY; i++) {
140 try {
141 return ds.beginTransaction();
142 } catch (DatastoreTimeoutException e) {
143 dte = e;
144 logger.log(Level.INFO, "This message["
145 + e
146 + "] is just INFORMATION. Retry["
147 + i
148 + "]", e);
149 sleep(wait);
150 wait *= WAIT_MULTIPLIER_FACTOR;
151 }
152 }
153 throw dte;
154 }

DatastoreUtil#beginTransaction()なのですが、最新のソースにはこのような処理はありません。
SDK側でリトライされるように変わったのかな?


2011/12/28 追記

こちらのエントリーに結論を書きました!
DatastoreTimeoutExceptionについて、時代は変わっていたようだ。 - SinDiary