c2340878
c2340878

Reputation: 409

How to make Java rest api call return immediately not wait?

@RequestMapping(value = "/endpoint", method = RequestMethod.POST)
    public ResponseEntity<?> endpoint(@RequestBody final ObjectNode data, final HttpServletRequest request) {
        somefunction();
        return new ResponseEntity<>(HttpStatus.OK);
    }


public somefunction() {
 .....
 }

In Java spring controller, I have an endpoint. When this endpoint is called, I want it return directly, not wait somefunction() to finish. Any could teach me how to deal with this?

Upvotes: 10

Views: 7222

Answers (3)

walen
walen

Reputation: 7273

If you are using Java 8, you can use the new Executor classes:

@RequestMapping(value = "/endpoint", method = RequestMethod.POST)
public ResponseEntity<?> endpoint(@RequestBody final ObjectNode data, final HttpServletRequest request) {
    Executors.newScheduledThreadPool(1).schedule(
        () -> somefunction(),
        10, TimeUnit.SECONDS
    );
    return new ResponseEntity<>(HttpStatus.ACCEPTED);
}

This will:

  1. Schedule somefunction() to run after a 10 second delay.
  2. Return HTTP 202 Accepted (which is what you should return when your POST endpoint does not actually create anything on the spot).
  3. Run somefunction() after 10 seconds have passed.

Upvotes: 15

xenteros
xenteros

Reputation: 15862

You should use RxJava which offers you promises. You will have DefferedResult which will be returned asynchronously, so it won't block other methods from being executed.

For example:

@RequestMapping("/getAMessageFutureAsync")
public DeferredResult<Message> getAMessageFutureAsync() {
    DeferredResult<Message> deffered = new DeferredResult<>(90000);
    CompletableFuture<Message> f = this.service1.getAMessageFuture();
    f.whenComplete((res, ex) -> {
        if (ex != null) {
            deffered.setErrorResult(ex);
        } else {
            deffered.setResult(res);
        }
    });
    return deffered;
}

--Code source and tutorial

Upvotes: 2

Chiu
Chiu

Reputation: 374

change line

somefunction();

to be

new Thread()
{
    public void run() {
        somefunction();
    }
}.start();

Upvotes: 4

Related Questions