sola's note -18ページ目

sola's note

日ごろのメモを書いていきます。何か新しいものを作るために。

セッションについて書き途中だけど、それは一旦置いといて
GAEのリクエスト制限について。

正直言って


 通 信 コ ス ト が ヤ バ イ


本家のサイトでも、紹介サイトでも
かなり強く言われている

1000件制限と30秒制限

これは

一回のリクエストで取得できる件数は1000件が上限ですよ

とか

一回のリクエストに30秒かかるとエラーが出ますよ

といった制限を意味している。
取得可能件数が1000件なのは、なんかちょっとイヤだが
プログラムをした事がある人なら

30秒制限はそう引っかからない

と思うだろう。
だがしかし


だがしかしだよ。


引っかかるんだよ。
結構あっさりと。

普通に考えたら、1リクエストで30秒なんてかかる処理なんて
システムとして破綻している
って思うけど、かかるのです。

特に 書 き 込 み 処 理

あまり叫ばれていない(?)けど、
噂では書きこみ処理は読み込み処理の

 5 倍

の時間を要するそう。
詳しく調べていないので、ソースは無いですが
実際

50件位のエンティティの書き込みをしようとすると

余裕でタイムアウトになる。
そう噂の

DeadLineExceededException

これ。
最近かなり親しくなってきた。

まあ要は、即時反映が必要なデータではなければ
cronとかキャッシュで対応して下さい
なんて言う事らしいが、

まさかここまで意識する必要があったとは

想定外ヽ(゚∀゚)ノ
作ってるプログラムのロジックを組み替えなければいけない。

通信コストを甘く見過ぎてた。
GAEでHttpSessionを使う

やっとここまで辿り着いた。
Google App Engine for Java(以下GAE)でHttpSessionを使います。

前々回前回 と奮闘した件についてのまとめ。

GAEで一時的な記憶処理として

・セッション(HttpSession)

・キャッシュ(MemcacheService)

がある。

今回はセッションについて。
セッションを使用するには絶対条件があり

appengine-web.xml



<sessions-enabled>true</sessions-enabled>

の記述を追加します。
多分ここまでは調べれば簡単に出てきます。

また、エンティティのモデルとなるクラスにSerializableをimplementsしてシリアライズ化します。


次に複合条件のようなもので、

・データストアから取得したデータをセッションにセットして使う場合はそのまま使用しない

というのが大事、
実際にどういう事かというと、

データストアからデータを取得する際は

PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery(Hoge.class);
List<Hoge> hogeList = (List<Hoge>) query.execute();

とやると思う。
しかし、ここで取得したhogeListをそのまま使用すると問題があるみたい。
というのも、データストアから取得したエンティティは
取得した時に使用したPersistenceManagerがクローズすると、
エンティティのステータスが変わってしまい、データの読み込みに支障が出るようです。
これを防ぐため、

hogeListCopy = (List<Hoge>)pm.detachCopyAll(hogeList);

という処理を行うと、エンティティの情報をコピーして使用することが出来ます。
この処理に関して記述してある本を見つけたのでついでにプッシュしておきます。
Google App Engine for Java [実践]クラウドシステム構築 (WEB+.../(株)グルージェント
¥2,604
Amazon.co.jp
セッションに関しては以上の点を守れば使えると思われます。
万が一記述漏れがあったら追記していきます。
前回Google App Engineでマジでセッションが効かない
でGAE/Jでセッションだmemcacheだ書いたけど
そのmemcacheについて少しわかったのでメモ。

前回はsessionに似ているやつがある~
なんて書いたけど、以下の点が明確に違うことが判明


memcacheはインスタンスが異なる場合でも持つ値が同じになる


どういうことかというと、
memcacheを使用する時は

MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();

でインスタンスを生成するわけだけど、
同じアプリケーション内でこれを実行した場合、
実行するクラスが異なっても、インスタンスが保持するキーと値の組み合わせは共有される。

悪く言うなら別々に保持できない。
共有したくないデータを扱う時にはそのままでは使えない。

インスタンス毎に値を持つためのクラスも存在するみたいだけど、
それはまだ使ってないからノータッチで。

そもそもインスタンス毎に値を持たせるとした場合、
こいつをわざわざ使う効果ってどれくらいあるのだろうか。