I'm looking for a Java pattern for making a nested sequence of non-blocking method calls. In my case, some client code needs to asynchronously invoke a service to perform some use case, and each step of that use case must itself be performed asynchronously (for reasons outside the scope of this question). Imagine I have existing interfaces as follows:
public interface Request {} public interface Response {} public interface Callback<R extends Response> { void onSuccess(R response); void onError(Exception e); }
There are various paired implementations of the Request
and Response
interfaces, namely RequestA
+ ResponseA
(given by the client), RequestB
+ ResponseB
(used internally by the service), etc.
The processing flow looks like this:
In between the receipt of each response and the sending of the next request, some additional processing needs to happen (e.g. based on values in any of the previous requests or responses).
So far I've tried two approaches to coding this in Java:
Is there some pattern to make this code more readable? For example, could I express the service method as a list of self-contained operations that are executed in sequence by some framework class that takes care of the nesting?
When using callbacks, you're required to put dependent program logic that is to be executed after an asynchronous operation has completed inside a callback. When you combine multiple such calls, you end up with deeply nested code. Deeply nested callbacks in JavaScript code.
In computer programming, a callback, also known as a "call-after" function, is any executable code that is passed as an argument to other code; that other code is expected to call back (execute) the argument at a given time. Programmatic Example. Callback is a simple interface with single method.
Error handling with callbacks When we're writing synchronous code, error handling is straightforward: when an error occurs, we simply throw an exception. In asynchronous code, things are not quite as simple, because the error may occur long after we've returned to our caller.
Since the implementation (not only the interface) must not block, I like your list idea.
Set up a list of "operations" (perhaps Future
s?), for which the setup should be pretty clear and readable. Then upon receiving each response, the next operation should be invoked.
With a little imagination, this sounds like the chain of responsibility. Here's some pseudocode for what I'm imagining:
public void setup() { this.operations.add(new Operation(new RequestA(), new CallbackA())); this.operations.add(new Operation(new RequestB(), new CallbackB())); this.operations.add(new Operation(new RequestC(), new CallbackC())); this.operations.add(new Operation(new RequestD(), new CallbackD())); startNextOperation(); } private void startNextOperation() { if ( this.operations.isEmpty() ) { reportAllOperationsComplete(); } Operation op = this.operations.remove(0); op.request.go( op.callback ); } private class CallbackA implements Callback<Boolean> { public void onSuccess(Boolean response) { // store response? etc? startNextOperation(); } } ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With