On Sun, Aug 2, 2020 at 10:47 AM Atri Sharma <a...@apache.org> 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 >