欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Send response and then process - async processing

程序员文章站 2022-03-10 23:13:20
...
If your request processing takes long time to run, client might be timed out before processing completed. One solution is to send back the response (method returns) and then process the request in a different thread.

/*
* This is the normal sync processing. Client might be timed out if 
* processing takes a while to finish and then the method returns.
*/
    @POST
    @Path("/test")
    public void test() {
        System.out.println("==== Normal test started");

        try {
            System.out.println("==== Normal task started: " + Instant.now());
            Thread.sleep(15000);
            System.out.println("==== Normal task finished: " + Instant.now());
        } catch (InterruptedException ie) {}

        System.out.println("==== Normal test completed");
    }

## console output: everything happens in order. If it took longer than 15 seconds, client could be timed out:
==== Normal test started
==== Normal task started: 2017-10-12T01:25:10.054Z
==== Normal task finished: 2017-10-12T01:25:25.055Z
==== Normal test completed


/* Async processing. The method would return immediately after the request received.
* processing(task) would happen afterwards, so that client would not be timed out.
*/
    @POST
    @Path("/testAsync")
    public Response testAsync() {
        System.out.println(">>>> Async test started");

        Runnable task = () -> {
            try {
                System.out.println(">>>> async task started: " + Instant.now());
                //Thread.sleep(15000);
                TimeUnit.SECONDS.sleep(15);
                System.out.println(">>>> async task finished: " + Instant.now());
            } catch (InterruptedException ie) {}
        };

        Executors.newSingleThreadExecutor().execute(task);

        System.out.println(">>>> Async test completed");
        return Response.status(OK).entity("service completed!").build();
    }

## console output: method returns immediately and then task starts in a different thread:
>>>> Async test started
>>>> Async test completed
>>>> async task started: 2017-10-12T01:25:33.673Z
>>>> async task finished: 2017-10-12T01:25:48.675Z



/**
* The following is jax-rs 2.0 AsyncResponse.
*/
    @POST
    @Path("/asyncResponse")
    public void testAsyncResponse(@Suspended AsyncResponse asyncResponse) {
        System.out.println("## testAsyncResponse started");

        new Thread() {
            public void run() {
                try {
                    System.out.println("## testAsyncResponse task started: " + Instant.now());
                    Thread.sleep(15000);
                    System.out.println("## testAsyncResponse task finished: " + Instant.now());
                } catch (InterruptedException ie) {}

                // Send processing result: if suspended AsyncResponse is not resumed or cancelled, client would be timed out
                Response response = Response.ok().entity("Processed Successfully").build();
                asyncResponse.resume(response);
            }
        }.start();

        System.out.println("## testAsyncResponse completed");
    }