We're updating the issue view to help you get more done. 

Execute blocking search result processing in another thread than the one used for HTTP requests

Description

This is mainly true for Elasticsearch, but Lucene might be affected in the future.

Interesting read if you're not familiar with completable futures: https://www.nurkiewicz.com/2015/11/which-thread-executes.html

In our current model, we register the post-processing of the JSON resulting from a SearchQuery as a subsequent step of a CompletableFuture. This is very, very wrong. The main reason is that such processing is executed in one of the threads used by the Elasticsearch client to handle HTTP requests and responses, and it’s a very small thread pool because it’s only expected to execute non-blocking operations. However, search result post processing includes potentially costly, blocking operations: the ORM entity loading.

The quick and easy solution, since our query APIs are all synchronous for now, would be to simply call future.join() to get the JsonObject, then execute the post-processing synchronously in {‌{SearchQuery.execute()}‌}.

But that's obviously not a long-term solution, since we want to ultimately be able to execute queries asynchronously (see HSEARCH‌-3322 ).

A more long-term solution would be to make the loading operation itself asynchronous (ObjectLoad.load would return a CompletableFuture<List<T>>}‌}. That would however require to define an executor (thread pool) in the ORM mapper.

It would be even better to be able to run loading in the client thread if this thread happens to be waiting for the completable future to complete, but I don't think this is currently possible.

Environment

None

Status

Assignee

Yoann Rodière

Reporter

Yoann Rodière

Labels

None

Suitable for new contributors

None

Feedback Requested

None

Fix versions

Priority

Critical