2016-08-04 23 views
0

私は、ユーザがmongoデータベースに対して地理空間クエリを実行しているアプリケーションを持っています。クエリは何千もの結果を返すことができます(〜50k)。これらの結果は、websocketを介してクライアントにストリーミングされます。ただし、ユーザーは結果の中間結果を中止して新しいクエリを実行できます。ユーザーは頻繁に1分間に数回のオーダでリクエストを開始、中止、再開します。場合によっては数秒ごとにキャンセル/再起動することもあります。実行中のクエリをキャンセルします

質問は、ユーザーがリクエストを打ち切ったときに、サーバー上でクエリを取り消して、何千もの不要な結果をストリーミングするリソースを引き留めないようにするにはどうすればいいですか?私は現在カーソル上でdestroy()と呼んでいますが、これが実際にサーバ上で実行されているクエリを停止していることは明らかではありません。

この場合、どのようなベストプラクティスですか?

答えて

0

これを試しましたか?

  1. db.currentOp()
  2. db.killOp(IDRETURNEDHE)

これは良いexampleです。

0

答えは、実装の詳細の多くに依存します。

サーバーがストリーミング結果の途中にある場合(たとえば、まだ送信していないか、すべてをキューに入れていないなど)、サーバーが以前の結果をキャンセルする必要があるというメッセージを受信した場合、その他のストリームと送信を停止するように指示します。どのように正確に行うかは、コードに完全に依存しており、われわれが知っているコードを示す必要があります。

dbクエリーは完了してから長いですが、サーバーがクライアントに結果をストリーミングするプロセスに入っている可能性があります。その場合、探しているデータベースではなく、クライアントへの応答をストリームするコードです。 node.js JSはシングルスレッドなので、別のリクエストがサーバー上で実際に実行されるのは、ストリーミングコードが非同期書き込み操作の一部であって、完了するのを待っている間だけです。特定のユーザーと一意に関連付けられたフラグを設定しなければならない可能性があります。ストリームコードは、各チャンクが送信される前にそのフラグをチェックする必要があります。キャンセルフラグが見つかった場合は、残りの結果の送信を中止することができます。

結果を明示的にチャンク(一度に500など)し、各チャンクの送信の間にキャンセルフラグをチェックすることで、取り消し可能にすることができます。

一方、すべてのデータがすでにサーバーのTCPレイヤーによってバッファーに入れられている場合、送信を停止する唯一の方法はwebSocketを切断してクライアントに再接続させることです。

+0

websocketを介してクライアントに結果を送信するのをキャンセルするコードが既に用意されています(あなたの提案に非常に似ています)。私の質問は、MongoDBレイヤーでクエリの実行をキャンセルしてからクライアントに結果をストリーミングすることに本当に特有のものです。 – herbrandson

+0

@herbrandson - あなたが話している特定のデータベースコードと、すべてが実行されるときを制御するシーケンシングコードを表示します。コードに関する質問には、関連コードを含める必要があります。 – jfriend00

関連する問題