On Sun, Aug 2, 2020 at 10:47 AM Atri Sharma <[email protected]> wrote:
> I am +1 to this approach. Some thoughts inline.
>
> How would query timeout be respected in this approach?
>
The backend would need to "complete exceptionally" with a timeout
exception we think is appropriate. It'd call
completableFuture.completeExceptionally(exception).
>
> The default approach might be configured to throw
>> UnsupportedOperationException, or perhaps might simply use an Executor to
>> get it done in an obvious way (assuming we can get ahold of an Executor
>> somewhere?).
>>
>
> Would that mean that we use an Executor to execute a single thread?
>
Either I don't know what you mean, or I suspect that you think I'm
referring to the synchronous (not asynchronous) code path), which I am
not. I am referring to what a proposed SolrClient.requestAsync should do
if the SolrClient impl doesn't have an underlying asynchronous mechanism.
I think I'm leaning towards using a configured executor, and if you don't
supply one then default to JDK ForkJoinPool.commonPool(). I am not
proposing changing SolrClient.request() (a synchronous method) to pass off
work to another thread (in an executor) unless it's already doing that for
some implementations (e.g. ConcurrentUpdateHttp2SolrClient).
> >>
> CompletableFuture, and which merely takes the SolrRequest parameter and
> nothing else. Alternatively the client could supply a CompletableFuture
> parameter that Solr will call complete() on etc. but that seems a bit less
> natural to the notion of a method that returns it's results, albeit with a
> wrapper.
>
> I would think that we allow users to specify their callback. One of the
> advantages of AsyncListener is that it a custom implementation can allow
> users to handle the behaviour of timeout and other events. We should retain
> that behaviour.
>
CompletableFuture is a swiss army knife. If a client wants to provide an
async callback, it can do that via the CompletableFuture *returned* by the
proposed API via completableFuture.whenComplete on the result. Code
example:
public static void main(String[] args) {
final CompletableFuture<String> future = requestAsync();
future.whenComplete((result, throwable) -> {
System.out.println("Handler executed; got: " + result + "
throwable: " + throwable);
});
}
public static CompletableFuture<String> requestAsync() {
final CompletableFuture<String> future = new CompletableFuture<>();
new Thread(() -> {
System.out.println("Starting async work");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Ending async work");
future.complete("hello world");
}).start();
return future;
}
The code will print the following (after some other stuff) before finally
exiting:
"Handler executed; got: hello world throwable: null"
The caller/client is also able to cancel the operation, and the backend can
have its own handler to react just-in-time without polling.
~ David
--
> Regards,
>
> Atri
> Apache Concerted
>