3

現在、私のチームで議論が行われており、他の見解に興味があります. さまざまな分析アルゴリズムとサービスを適用してドキュメントに注釈を付ける役割を持つ RESTful Web サービスがあるとします。基本的なやり取りは明確です。ドキュメント コレクションであるリソースがあります。クライアントは新しいドキュメントをコレクションに POST し、新しいドキュメントの URI を取得し、それを GET しdocURIてドキュメントを取得したり、GETして名前付きエンティティなどの{docURI}/metadata一般的なメタデータを表示したりできます。問題は、一部の分析が{docURI}/ne完了までに時間がかかる場合があります。UI で部分的な結果または増分結果を表示できるようにするため、分析が完了する前にクライアントがメタデータ URI を取得するとします。今後 GET を繰り返すと、より多くの結果が得られる可能性があります。

これまでに説明したソリューションには、次のものがあります。

  • すべての分析が完了するまで HTTP 接続を開いたままにしておく (これはスケーラブルではないようです)
  • content-lengthとヘッダーを使用 accept-range して増分コンテンツを取得します (ただし、最終的なコンテンツの長さは事前にわかりません)
  • リソースごとに Atom フィードを提供して、クライアントが単にリソースを GET するのではなく、更新イベントをサブスクライブするようにする (アクティブなドキュメントが多数ある場合は、非常に複雑で、リソースを大量に消費する可能性があります)
  • GET がその時点で利用可能なものを返すようにするだけです (ただし、最終的にいつ終了したかをクライアントが認識しているという問題は残ります) [コメントに続く冪等性への参照を削除するために編集] .

RESTful アーキテクチャで長期間または非同期の対話を処理するための代替方法について、意見や提案はありますか?

イアン

4

7 に答える 7

3

次の方法で実装します。

1) クライアントがメタデータを要求する
2) サーバーが実際のデータ (既に利用可能な場合) または NotReady マーカーを返す
3) クライアントがサーバーにいつデータが利用可能になるかを尋ねる (このステップは前のステップとマージすることができる)
4) サーバーが時間間隔を返す (あるかもしれない)実行中のジョブの総数に関するいくつかのヒューリスティックなど)
5) クライアントは指定された期間待機し、ステップ 1 に進みます。

このようにして、できるだけ早くクライアントにデータを提供できます。ステップ 4 で返された遅延間隔を調整することで、サーバーの負荷を調整できます)。

于 2008-09-23T10:16:25.510 に答える
3

リソースごとに Atom フィードを提供して、クライアントが単にリソースを GET するのではなく、更新イベントをサブスクライブするようにする (アクティブなドキュメントが多数ある場合は、非常に複雑で、リソースを大量に消費する可能性があります)

SUPを検討したことがありますか?

ポーリングがオプションである場合、わざわざフィードを使用する必要はありません。クライアントにリソース自体をポーリングさせないのはなぜですか?

分析が完了するまでの推定時間を含めることで、不要なポーリングを削減できますか?

于 2008-09-23T10:18:59.030 に答える
2

HTTP202Acceptedを使用します。

また、 RESTfulWebサービスもチェックしてください。ここで私は上記について学びました。

于 2008-09-23T10:42:13.327 に答える
2
  • 冪等性を無視し、GET がその時点で利用可能なものを返すようにするだけです (ただし、最終的に完了したことをクライアントが認識しているという問題は残ります)。

時間の経過とともに異なる結果を返す GET は、冪等ではないことを本当に意味するのでしょうか? 仕様は次のように述べています。

メソッドは、(エラーや有効期限の問題は別として) N > 0 の同一のリクエストの副作用が単一のリクエストの場合と同じであるという点で、「冪等性」のプロパティを持つこともできます。

つまり、GET を複数回呼び出すと、呼び出し自体に副作用がない限り、異なる結果が返される場合があります。

その場合、REST メソッドは、条件付き GET およびキャッシュ メカニズムを使用して、いつ完了したかを示すことができます。

  • 分析の進行中、GET {docURI}/metadata応答には次のものが含まれる可能性があります。
    • 将来の数秒に設定されたExpiresヘッダー。
    • ETagヘッダーなし。
  • 分析が完了すると、そのリソースに対する応答は次のようになります。
    • Expiresヘッダーなし。
    • ETag。_ を使用した後続のリクエストは、ETagを返す必要があり304 Not Modifiedます。

注意: Expires だけでなく、キャッシュに関連する他の応答ヘッダーを検討することもできます。

これは、RESTful な設計のように感じられます。Web ブラウザーがこのリソースに対して連続して要求を行ったときに、正しいことを行っていることが想像できます。

于 2008-09-23T11:02:23.480 に答える
1

あなたのケースに適しているかもしれないし、そうでないかもしれない1つの代替ソリューションは、「AnnotationRequests」と呼ばれる新しいエンドポイントを追加することです。ドキュメント(またはドキュメントへのリンク)をAnnotationRequestsエンドポイントに投稿すると、クライアントがプロセスのステータスをポーリングできる場所( http://example.org/AnnotationRequest/2042など)が返されます。プロセスが完了すると、「AnnotationRequest」表現に完成したドキュメントへのリンクを含めることができます。

これの優れた副作用の1つは、AnnotationRequestsでGETを実行できるため、現在処理中のドキュメントを確認できることです。AnnotationRequestsを保持する期間を決定するのはあなた次第です。それらがいつ、誰によって、どのくらいの時間かかったか、または定期的にそれらを捨てることができるかについての完全な履歴を保持することは価値があるかもしれません。

于 2008-09-24T13:05:12.007 に答える
1

UdiDahanの nServiceBusをチェックすることをお勧めします。

于 2008-09-26T13:38:59.980 に答える
1

「その時点で利用可能なものをGETで返すだけ」というのは非常に理にかなっています。ただし、彼らがポーリングしているときは、彼らがすでに知っているものを返し続けたくありません。回答は、ポーリングするたびに長くなります。

GETリクエストで「これまでに見たもの」を提供する必要があります。これにより、冪等性が得られます。チャンク 1 を要求すると、常に同じ答えが得られます。チャンク 1 を見たら、チャンク 2 を要求できます。

答えは大きくなりません。より多くのピースが利用可能になります。「コレクション レベル」の GET は、応答のサイズを提供します。利用可能な各ピースに対して「詳細レベル」の GET があります。

基本的に、これは TCP/IP 確認応答のようなアルゴリズムです。彼らがピースを受け取ったら、あなたは次のピースを送ります。次のピースがある場合は、200-nothing new をレポートに送信します。

「最終的にいつ完了したかをクライアントが知る問題」は計り知れません。彼らは知ることができず、あなたはそれがどれくらいかかるかを予測することもできません.

「忙しい待機」、つまり、まだ完了しているかどうかを確認するためのポーリングを行う必要はありません。これは、サーバーにかなり大きな負荷がかかります。彼らがせっかちな場合。彼らの要求を抑制することができます。xが徐々に大きくなる「x秒でチェックバック」を送信できます。

ポーリングするとスコアが下がり、X 秒間ポーリングしないとスコアが上がる Unix スタイルのスケジューラ アルゴリズムを使用することもできます。

別の方法は、結果をポストするある種のキューです。これを行うには、完了したことを伝えるために POST できる URI を提供する必要があります。

または、軽量のポーリング アーキテクチャに Atom を使用します。Atom は複雑に見えますが (それでもポーリングが必要です)、完了するまで最小限の Atom 回答 (「まだ変更されていません」) を提供し、(「新しい結果」) を提供するときは、実際の重い get を実行できるようにします。これは、上記のインクリメンタル レスポンス手法ではなく、オール オア ナッシングです。

また、「コレクション レベル」の GET をプロセス全体の Atom ステータスと考えることができます。

于 2008-09-23T22:10:28.710 に答える