mad_fox
mad_fox

Reputation: 3188

Async Spring Rest Controller - Process future result

I am new to futures and I am trying to figure out how I can process the Listenable future in this senario:

@Controller
@EnableAutoConfiguration
public class ListenableFutureAsyncController {

    @Autowired
    IHeavyLiftingService heavyLiftingService;

    @RequestMapping("/")
    @ResponseBody
    DeferredResult<String> home() {
        // Create DeferredResult
        final DeferredResult<String> result = new DeferredResult<>();

        //Call to the async service
        ListenableFuture<ResponseEntity<String>> future = heavyLiftingService.heavyLifting();

        future.addCallback(
          new ListenableFutureCallback<ResponseEntity<String>>() {
            @Override
            public void onSuccess(ResponseEntity<String> response) {
                result.setResult(response.getBody());
            }

            @Override
            public void onFailure(Throwable t) {
                result.setErrorResult(t.getMessage());
            }
        });
        // Return the thread to servlet container, 
        // the response will be processed by another thread.
        return result;
    }

}

How can I process the future here other than passing it back to the controller. Ex. What if I want to save the future string to the db?

@Service
public class HeavyLiftingServiceImpl implements IHeavyLiftingService {

    public ListenableFuture<String> heavyLifting() {
        AsyncRestTemplate asycTemp = new AsyncRestTemplate();
        ListenableFuture<String> future = asycTemp.execute(url, method, requestCallback, responseExtractor, urlVariable);
        /** 
        /Save future string to db
        **/
        return future;
    }
}

Upvotes: 0

Views: 2792

Answers (1)

mad_fox
mad_fox

Reputation: 3188

I have found a way to do this using Spring's ListenableFutureAdapter

@Service
public class HeavyLiftingServiceImpl implements IHeavyLiftingService {

    public ListenableFuture<String> heavyLifting() {
        AsyncRestTemplate asycTemp = new AsyncRestTemplate();
        ListenableFuture<String> future = asycTemp.execute(url, method, requestCallback, responseExtractor, urlVariable);

        ListenableFutureAdapter<String, String> chainedFuture;
        chainedFuture = new ListenableFutureAdapter<String, String>(future) {

            @Override
            protected String adapt(String adapteeResult)
                    throws ExecutionException {
                        String parsedString = parse(adapteeResult);
                        return adapteeResult;
            }
        };

        return chainedFuture;
    }

}

I would recommend using Guava's implementation of listenable future. I find it more readable and documentation on chaining them together is easier to find.

Upvotes: 3

Related Questions