javaasynchronouscallbackcompletable-futurecallable

How can a Callable return a value from a predefined void callback?


I am using a data-related API interface which has a key void callback function that is automatically invoked to mark the end of some IO operations. I want to make the class Callable<String> and use Future<String> result.

I struggle to figure how to make the Callable return a String. Making a String returnResult(){return this.result} function to call inside doesn't do.

Please advise.

It looks something like:

public class MyCallable implements someAPIWrapper, Callable<String> {
    
    String result;

    @Override
    public void endOfJobCallback() { //predefined API callback marking end of work
      /*
      usually read the data and write to a file, but not my case.
      how to return this.result string from here?
      */
    }

    @Override
    public String call() throws Exception {
      //some logic stuff
      //make API call to request a bunch of data
      //inside a loop to listen to incoming messages, receiving and appending to the *result* variable
      //end of all messages signalled by the ending callback, stop loop and return result var
    }

}

class Main {
    public static void main(String[] args){
      MyCallable callable = new MyCallable();
      ExecutorService executor = Executors.newFixedThreadPool(2);
      Future<String> future = executor.submit(callable);
      String result = future.get(); //blocking until result ready
    }
}

Solution

  • You can use an (atomic) Boolean to know when to stop looping:

    public class MyCallable implements someAPIWrapper, Callable<String> {
        
        String result;
        private volatile boolean complete = false;
    
        @Override
        public void endOfJobCallback() { //predefined API callback marking end of work
          complete = true; //set Boolean to true atomically so that the other method will know you have been called
        }
    
        @Override
        public String call() throws Exception {
          while (!complete) {
            //Do your stuff
          }
          //if you reach this the callback was called
          return result;
        }
    
    }
    

    Note: it is unclear how exactly you listen to messages because you didn't add any code. You may want to take the idea and adapt it to the real code depending on whether you short poll, you have a webhook etc