3

GWT/GAE アプリを設計する際に、クライアント側 (GWT) が 3 種類の要求を生成することが明らかになりました。

  • Synchronous - 「今すぐ応答してください! 私は重要な人物であり、リアルタイムの応答が必要です!!!」
  • 非同期- 「できるときに答えてください。ある時点で答えを知る必要がありますが、実際にはそれほど緊急ではありません。」
  • コマンド- 「答えは必要ありません。これは実際には要求ではありません。サーバー側で何かを実行または処理するための単なるコマンドです。」

私のゲームプランは、GWT コードを実装して、特定のサーバー側の要求ごとに指定できるようにすることです (注:RequestFactoryこの質問の範囲外の理由で、従来の GWT-RPCを使用することにしました)。リクエスト:

  • SynchronousRequest- 同期 (上から); コマンドを送信し、何らかの方法でクライアントの状態を更新するために使用する応答を熱心に待ちます
  • AsynchronousRequest- 非同期 (上から); 最初のリクエストを作成し、ポーリングまたは GAE Channel API のいずれかを介して、レスポンスが最終的に受信されたときに通知されます
  • CommandRequest- コマンド (上から); サーバー側の要求を作成し、応答を待ちません (サーバーがコマンドの実行に失敗したり拒否したりしても)

私の意図SynchronousRequestは、完全にブロックするリクエストを生成することではないと思いますが、ユーザーWidgetが画面の特定または一部と対話する機能をブロックする可能性があります。

ここで追加されたキッカーは次のとおりです。GAE は、すべてのフロントエンド インスタンスにタイムアウトを強く適用します (60 秒)。バックエンド インスタンスでは、タイムアウトやスレッド化などの制約がはるかに緩和されています。そのため、GAE タイムアウトが問題にならないようにバックエンド インスタンスにルーティングする必要があることは明らかAsynchronousRequestsですCommandRequests

ただし、GAE の動作が悪い場合、またはトラフィックがピークに達している場合、またはコードが単純にうまくいかない場合は、aSynchronousRequestが作成されるシナリオを説明する必要があります (タイムアウトによって調整されたフロントエンド インスタンスを通過する必要があります)。私のGAEサーバーコードが何か特別なことをしない限り、タイムアウトします。GAE API には、リクエストがタイムアウトするまでのミリ秒数を確認するために呼び出すことができるメソッドがあることを知っています。しかし、その名前は今のところわかりませんが、この「派手な」コードの基になっているものです。public static long GAE.timeLeftOnRequestInMillis()この質問のためにそれを呼び出しましょう。

このシナリオでは、 aSynchronousRequestがタイムアウトしようとしていることを検出し、何らかの方法で動的に a に変換して、タイムアウトにならないようにしたいと考えAsynchronousRequestています。おそらく、これは をAboutToTimeoutResponseクライアントに送り返すことを意味し、クライアントに として再送信するAsynchronousRequestか、単に失敗するかを決定させることになります。あるいは、 を に変換して、バックエンド インスタンスがそれを消費し、処理して応答を返すキューにプッシュすることもできSynchronousRequestますAsynchronousRequest。実装に関しては、サーバーが十分に速く処理できなかったためにリクエストが失敗したりタイムアウトしたりしない限り、好みはありません(GAEが課す規制のため)。

それでは、ここで私が実際に求めているのは次のとおりです。

  • 内でRequestFactory呼び出しをラップするにはどうすればよいですか? また、呼び出しがそれぞれの意図どおりに動作するようにするにはどうすればよいですか? 言い換えれば、呼び出しが部分的にブロックされる (同期) か、途中で通知/更新される (非同期) か、単に起動して忘れられる (コマンド) か?SynchronousRequestAsynchronousRequestCommandRequestRequestFactory
  • SynchronousRequestGAE の 60 秒のタイムアウトをバイパスし、失敗することなく処理できるようにする要件を実装するにはどうすればよいですか?

注意: タイムアウトの問題は、バックエンド インスタンスに再ルーティングすることで簡単に回避できますが、バックエンドはスケーリングできません。ここでもスケーラビリティが必要です (それが、そもそも GAE を使用している主な理由です!) - そのため、スケーラブルなフロントエンド インスタンスとそのタイムアウトを処理するソリューションが必要です。前もって感謝します!

4

1 に答える 1

0

GAE に実行させたい計算に 60 秒以上かかる場合は、応答を送信する前に結果が計算されるのを待たないでください。問題の定義によると、これを回避する方法はありません。代わりに、クライアントは作業指示書を送信し、結果の準備が整ったときにサーバーからの通知を待つ必要があります。リクエストは、次のような作業指示書で構成されます。

class ComputeDigitsOfPiWorkOrder {
  // parameters for the computation
  int numberOfDigitsToCompute;

  // Used by the GAE app to contact the requester when results are ready.
  ClientId clientId;
}

このように、GAE アプリは作業指示書が (タスク キューなどに) 保存されるとすぐに応答でき、10 億桁の pi の計算が実際に終了するまで待つ必要がありません。その後、GWT クライアントは Channel API を使用して結果を待ちます。

一部の作業指示書の優先度を高くするために、複数のタスク キューを使用できます。タスク キューの作業を自動的にスケーリングする場合は、プッシュ キューを使用します。プッシュ キューを使用して優先度を実装するのは少し難しいですが、優先度の高いキューを構成してフィード レートを速くすることができます。

Channel API を他の通知ソリューションに置き換えることもできますが、おそらくそれが最も簡単です。

于 2012-09-27T06:57:19.410 に答える