Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java pattern for nested callbacks?

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:

Sequence diagram showing nested callbacks.

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:

  • anonymous classes: gets ugly quickly because of the required nesting
  • inner classes: neater than the above, but still hard for another developer to comprehend the flow of execution

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?

like image 612
Andrew Swan Avatar asked May 22 '12 02:05

Andrew Swan


People also ask

Can we use nested callbacks?

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.

What is callback design pattern?

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.

What is the problem with callbacks explain in brief?

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.


1 Answers

Since the implementation (not only the interface) must not block, I like your list idea.

Set up a list of "operations" (perhaps Futures?), 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();     } } ... 
like image 196
Rob I Avatar answered Sep 23 '22 05:09

Rob I