何らかの理由で、これを実装することに頭を悩ませることはできません。Elastic Searchを呼び出すアプリケーションをPlayで実行しています。私の設計の一環として、私のサービスは、このブログ投稿に示されているように、scala future でラップされた Java API を使用しています。その投稿のコードを更新して、次のようにブロッキング I/O を実行することを ExecutionContext に示唆しました。
import scala.concurent.{blocking, Future, Promise}
import org.elasticsearch.action.{ActionRequestBuilder, ActionListener, ActionResponse }
def execute[RB <: ActionRequestBuilder[_, T, _, _]](request: RB): Future[T] = {
blocking {
request.execute(this)
promise.future
}
}
ES に送信するクエリを作成する実際のサービスは、コンストラクター パラメーターとして executionContext を受け取り、エラスティック サーチの呼び出しに使用します。これを行ったのは、play が使用するグローバル実行コンテキストが、ES へのブロッキング呼び出しによってスレッドが拘束されないようにするためです。この SO コメントは、グローバル コンテキストのみがブロックを認識していることに言及しているため、独自のコンテキストを作成する必要があります。その同じ投稿/回答には、ForkJoin プールの使用に関する多くの情報がありますが、それらのドキュメントに書かれている内容を取得し、ブロッキング ドキュメントのヒントと組み合わせて、ブロッキングに応答する実行コンテキストを作成する方法がわかりません。ヒント。
私が抱えている問題の 1 つは、そもそもブロッキング コンテキストにどのように対応すればよいかわからないことだと思います。私はベストプラクティスを読んでいましたが、それが使用する例はスレッドの無制限のキャッシュです:
ここでは、無制限の「キャッシュされたスレッドプール」を使用することを好むため、制限がないことに注意してください。ブロッキング I/O を行う場合、ブロックできる十分な数のスレッドが必要であるという考えがあります。ただし、無制限が多すぎる場合は、ユースケースに応じて、後で微調整できます。このサンプルのアイデアは、ボールを転がすことです。
これは、ForkJoin でサポートされているスレッド プールを使用して、非ブロッキング I/O を処理するときにキャッシュされたスレッドを使用し、IO をブロックするための新しいスレッドを作成する必要があることを意味しますか? または、他の何か?個別のスレッド プールの使用についてオンラインで見つけたほぼすべてのリソースは、Neophytes ガイドが行うことを行う傾向があります。つまり、次のようになります。
さまざまなスレッド プールを調整する方法は、個々のアプリケーションに大きく依存するため、この記事の範囲を超えています。
アプリケーションに依存することはわかっていますが、この場合は、何らかのタイプのブロッキング対応の ExecutionContext を作成し、スレッドを管理するための適切な戦略を理解したい場合です。コンテキストがアプリケーションの特定の部分用である場合、固定スレッド プール サイズを作成blocking
し、そもそもキーワードを使用/無視しないようにする必要がありますか?
私はとりとめのない傾向があるので、回答で探しているものを分解しようとします。
- コード!これらのドキュメントをすべて読んでも、ブロッキングを意識したコンテキストをコーディングすることはできないと感じているので、例を示していただければ幸いです。
- ブロッキングスレッドを処理する方法に関するリンクまたはヒント。つまり、それらのために新しいスレッドを無限に作成し、使用可能なスレッドの数を確認し、多すぎる場合は拒否します。他の戦略
- ここでパフォーマンスのヒントを探しているわけではありません。テストでしか得られないことはわかっていますが、そもそもコンテキストをコーディングする方法がわからない場合はテストできません! ForkJoins と threadpools の例を見つけましたが、重要な部分が欠けてい
blocking
ます。
ここで長い質問をして申し訳ありません。私が見ているものの感覚をあなたに伝えようとしているだけで、1 日以上この問題に頭を悩ませようとしていて、外部の助けが必要です。
編集:これを明確にするために、ElasticSearch サービスのコンストラクターの署名は次のとおりです。
//Note that these are not implicit parameters!
class ElasticSearchService(otherParams ..., val executionContext: ExecutionContext)
そして、私のアプリケーションの起動コードには、次のようなものがあります。
object Global extends GlobalSettings {
val elasticSearchContext = //Custom Context goes here
...
val elasticSearchService = new ElasticSearchService(params, elasticSearchContext);
...
}
私はPlay の contexts に関する推奨事項も読んでいますが、ヒントのブロックについてはまだ何も見ていませんBlockContext
。