2011年9月30日金曜日

Google App Engine for Java の非同期データストアAPIの呼び出し(その4)

Google App Engineのデータストアは、
非同期に呼び出して結果を取得することも出来ます。

英語版ドキュメントはこちら。
その1,その2,その3も参照してみてください。

Working with Futures (Futureの使用)

Future のJavadocは、非同期データストアAPIから返されたFutureを上手く使用する上で知る必要のあることのほとんどを説明していますが、App Engine固有の注意点があります。
・Future.get(long timeout, TimeUnit unit)メソッドを呼び出した時に、timeoutはAsyncDatastoreServiceを生成した時点のRPCデッドラインのセットから切り離されています。詳しくは、datastore RPC deadlinesのドキュメントを参照してください。
・Future.cancel(boolean mayInterruptIfRunning)メソッドを呼び出し、trueが返された場合、データストアの状態が変更されていないことを必ずしも意味するものではありません。言い換えると、Futureをキャンセルすることは、トランザクションをロールバックすることと同じではありません。

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年9月26日月曜日

Google App Engine for Java の非同期データストアAPIの呼び出し(その3)

Google App Engineのデータストアは、
非同期に呼び出して結果を取得することも出来ます。

英語版ドキュメントはこちら。
その1はこちら,その2はこちら。


Workind with Async Transactions 非同期トランザクションの使用

非同期データストアAPI呼び出しは、同期呼び出しと同じようにトランザクションに参加することができます。ここで挙げるのは、従業員の給料の額を調整し、Employeeと同じエンティティグループにSalaryAdjustmentエンティティを1つのトランザクション内で追加して書き込みます。

void giveRaise(AsyncDatastoreService datastore, Key employeeKey, long raiseAmount)
        throws Exception {
    Future txn = datastore.beginTransaction();

    // Async call to lookup the Employee entity
    Future employeeEntityFuture = datastore.get(employeeKey);

    // Create and put a SalaryAdjustment entity in parallel with the lookup
    Entity adjustmentEntity = new Entity("SalaryAdjustment", employeeKey);
    adjustmentEntity.setProperty("adjustment", raiseAmount);
    adjustmentEntity.setProperty("adjustmentDate", new Date());
    datastore.put(adjustmentEntity);

    // Fetch the result of our lookup to make the salary adjustment
    Entity employeeEntity = employeeEntityFuture.get();
    long salary = (Long) employeeEntity.getProperty("salary");
    employeeEntity.setProperty("salary", salary + raiseAmount);

    // Re-put the Employee entity with the adjusted salary.
    datastore.put(employeeEntity);
    txn.commit(); // could also call txn.commitAsync() here
}

このサンプルは、トランザクション無しの非同期呼び出しとトランザクション内での非同期呼び出しの違いを示しています。トランザクションを利用していない場合、独立した非同期呼び出しの官僚を確認する唯一の方法は、呼び出しが行われた時に戻されたFutureの値を取得するということになります。トランザクションを利用すると、Transaction.commit()の呼び出しが、トランザクション開始からコミットされる前までの全ての非同期呼び出しの結果をブロックします。

そのため、上記の例では、SalaryAdjustmentエンティティの挿入を行う非同期呼び出しがtxn.commit()を呼び出された時点では未解決の可能性があるにもかかわらず、挿入が完了するまでにコミットは起こりません。同様に、txn.commit()の代りにtxn.commitAsync()の呼び出しを選択すると、commitAsync()から返されたFutureのget()メソッド呼び出しが全ての未解決の非同期呼び出しが干渉するまでブロックします。

ノート:トランザクションは特定のスレッドに関連付けられますが、DatastoreServiceやAsyncDfatastoreServiceの特定のインスタンスには関連付けられません。これの意味するところは、あるDatastoreServiceからトランザクションを開始して、
あるAsyncDatastoreServiceから非同期呼び出しを行うと、非同期呼び出しはトランザクションに参加する、ということです。または、もっと簡潔に言えば、
DatastoreService.getCurrentTransaction()とAsyncDatastoreService.getCurrentTransaction()は常に同じトランザクションを返すということです。

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年9月25日日曜日

Google App Engine for Java の非同期データストアAPIの呼び出し(その2)

Google App Engineのデータストアは、
非同期に呼び出して結果を取得することも出来ます。

英語版ドキュメントはこちら。
その1はこちら。

Working with the Async Datastore Service (非同期データストアサービスの使用)

非同期データストアAPIでは、AsyncDatastoreServiceインターフェイスのメソッドを使ってデータストア呼び出しを行います。このオブジェクトはDatastoreServiceFactoryクラスのgetAsyncDatastoreService()クラスメソッドを呼び出して
取得します。

import com.google.appengine.api.datastore.AsyncDatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;

// ...
AsyncDatastoreService datastore = DatastoreServiceFactory.getAsyncDatastoreService();

AsyncDatastoreServiceは、結果の取得を後の時点でブロックすることが出来るFutureを直ちに返すメソッドを除いて、DatastoreServiceと同じ操作をサポートしています。例として、DatastoreService.get()は1つのエンティティを返しますが、AsyncDataStoreService.get()はFuture<Entity>を返します。

// ...

Key key = KeyFactory.createKey("Employee", "Max");
// Async call returns immediately
Future<entity> entityFuture = datastore.get(key);

// Do other stuff while the get operation runs in the background...

// Blocks if the get operation has not finished, otherwise returns instantly
Entity entity = entityFuture.get();

ノート:get()メソッドを呼び出すまでは例外はスローされません。このメソッドの呼び出しは非同期操作の成功/不成功の検査に利用できます。

AsyncDatastoreServiceを取得しているけれども同期した操作の実行を必要とする場合、適切なAsyncDatastoreServiceのメソッドを呼び出してからすぐにresultのブロックをかけます。

// ...

Entity entity = new Employee("Employee", "Alfred");
// ... populate entity properties

// Make a sync call via the async interface
Key key = datastore.put(key).get();

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年9月22日木曜日

Google App Engine for Java の非同期データストア呼び出し

Google App Engineのデータストアは、
非同期に呼び出して結果を取得することも出来ます。

英語版ドキュメントはこちら。


Async Datastore API (非同期データストアAPI)

非同期データストアAPIは、リクエストのハンドリングよりも後の時点で、並列にブロッキングされないデータストア呼び出しから結果を取得することを可能にします。このドキュメントは非同期データストア呼び出しの以下の側面を記述しています。
・Working with the Async Datastore Service 非同期データストアサービスの動作
・Working with Async Transactions 非同期トランザクションの動作
・Working with Futures Futureの動作
・Async Queries 非同期クエリ
・When To Use Async Datastore Calls 非同期データストア呼び出しの使用タイミング


インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年9月19日月曜日

Google App Engine のHigh Replication Datastoreの利用(その5)

前回まででGoogle App Engine の
High Replication Datastoreの使用についてのドキュメントを翻訳しました。
(原文はこちら)

データストアには2種類あり、
・High Replication Datastore
・Master/Slave Datastore
です。

GAEのデータストアは、データを複数のデータストアに
保存しますが、データストアへのアクセスの仕方に違いがあります。

マスター/スレーブデータストアは、
プログラムからアクセスされるデータストアは1つで
保存・読み出しをする先は複数になります。
マスターデータストアに障害が発生すると、
データストアの読み書きが出来なくなるという欠点があります。

High Replication Datastore(HRD)は、
アクセスするデータストアを1つに限定しないので
可用性が上がります。有料版は99.95%の保障をしています。
(これまでのところ、実運用上で99.99%以上のようです)
しかし、書き込みを開始してから全体の更新が完了する
までに読み出しが行われると、
読み出されたデータが最新のものであるとは限りません。
そのため、アプリケーションの性質によっては
レスポンスに最新の更新が反映されるような工夫が必要となる、
ということのようです(それが、前回の内容)。

マスター/スレーブを使用すればいい…のですが、
今後廃止となる予定だそうです。

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年9月15日木曜日

Google App Engine for Java のHigh Replication Datastoreの使用(その4)

Google App Engine for Javaのデータストアには2種類あり、
そのうちの1つを選択して使用します。

9月9日の記事から、2種類のデータストアのうちの
High Replication Datastore(高レプリケーションデータストア、HRD)の
使用方法についてのドキュメントの翻訳です。

原文はこちらです。
前回の翻訳はこちら。

使用上の注意

上記の高レプリケーションデータストアのサンプルコードは1つのゲストブックあたりに単一のエンティティグループとなるように書かれています。これは単一のゲストブック上のクエリには強い一貫性を与えますが、1秒当たり1回の書き込み(エンティティグループへのサポートの制限)を行うようにゲストブックを制限するようになります。従って、1つのゲストブックあたりに単一のエンティティグループに書き込みを行うのは高い頻度での利用が
見込まれる場合には最適ではありません。アプリケーションが高い書き込み要求に遭遇する可能性が高い場合、別の手段を使用することを検証してください。例として、最近の投稿を有効期限付きでmemcacheにputして、その後、データストアから取得した投稿とmemcacheからの最近の投稿を合わせた結果を表示する方法があります。
最終的な一貫性として、数秒内に実行されるクエリに対しては書き込みの99.9%以上に対して利用できます。アプリケーションに投稿するのにかかる時間の間に、現在のユーザーへデータを提供するための解決方法を見つけることが目標となります。解決方法として、memcacheを使用したり、クッキーに保存したり、URLに状態を付け加えたり、その他全く別の方法があるかもしれません。ポイントは、投稿のコンテキストにある現在のユーザーにデータを提供する方法が、高レプリケーションデータストアが完全に許容する最終的な一貫性を作り出すために十分となるようにすることです。get(),put()やトランザクションを行うと、常に直前に書き込まれたデータを参照するということを忘れないで下さい。

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年9月12日月曜日

Google App Engine for Java のHigh Replication Datastoreの使用(その3)

Google App Engine for Javaのデータストアには2種類あり、
そのうちの1つを選択して使用します。

前々回から、2種類のデータストアのうちの
High Replication Datastore(高レプリケーションデータストア、HRD)の
使用方法についてのドキュメントの翻訳です。

原文はこちらです。
前回の翻訳はこちら。


In the High Replication Datastore (高レプリケーションデータストア)

高レプリケーションデータストアでは、サンプルのゲストブックアプリケーションはキー名guestbookNameと共にGuestbookカインドの親キーを使い、その後のあいさつ文を親キーによって判別されるエンティティグループ内に保存します。
String guestbookName = req.getParameter("guestbookName");
        Key guestbookKey = KeyFactory.createKey("Guestbook", guestbookName);
        String content = req.getParameter("content");
        Date date = new Date();
        // Places the greeting in the same entity group as the guestbook
        Entity greeting = new Entity("Greeting", guestbookKey);
        greeting.setProperty("user", user);
        greeting.setProperty("date", date);
        greeting.setProperty("content", content);
あいさつ文用クエリは、特定のguestbookに追加された挨拶のみを見つける祖先クエリを実行するために親であるGuestbookキーを使います。:
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    Key guestbookKey = KeyFactory.createKey("Guestbook", guestbookName);
    Query query = new Query("Greeting", guestbookKey).addSort("date", Query.SortDirection.DESCENDING);
    query.setAncestor(guestbookKey);
    List<Entity> greetings = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(10));

インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/