Should we always use Asynchronous JAX-RS resources For mobile backend?

强颜欢笑 提交于 2019-12-23 05:25:27

问题


I am building Mobile backend API using Java EE - JAX-RS 2.0 technology.

Since most of mobile client consumes are asynchronous http calls

so my question is: Should I use asynchronous feature for all JAX-RS resources? And the reason if not?

The below is the template Mobile Async API

@Path("/async_api")
public class AsyncResource {

    @GET
    @Path("/loadUsers")
    @Produces(MediaType.APPLICATION_JSON)
    public void loadUsers(@Suspended AsyncResponse asyncResponse) {

        //TODO: ManagedExecutorService

        new Thread(new Runnable() {

            @Override
            public void run() {
                List users = loadBigUsers();
                asyncResponse.resume(users);
            }

            private List loadBigUsers() {
                return null; // Return big list
            }

        }).start();
    }
}

Thank you!


回答1:


In JAX-RS the @Suspendannotation and AsyncResponse are needed only in certain typical scenarios. The first scenario was already identified in your code example. It is long running tasks. In this case the AsyncResponse can be used to execute long running code in a background thread. While this would not make sense at the first glance we need to think about how an application server / container handles its requests. Usually there is a pool of threads that accepts and handles client requests. If you implement expensive operations inline in your JAX-RS service methods one of the threads in the pool is blocked for the entire runtime. With the AsyncResponse the executor thread gets returned to the pool and other requests can be served in parallel.

@Path("/users")
public class UserRestService {

    @GET
    public void getAllUsers(@Suspend final AsyncResponse asyncResponse) {
        new Thread(new Runnable(
            @Override
            public void run() {
                List<Users> users = UserDAO.loadAllUsers();
                asyncResponse.resume(users);
            }
        ) {}).start();
    }
}

The second application scenario for AsyncResponse is the often seen pattern of producer consumer patterns. Assuming you have a queue bound to the URL https://yourservice.at/queue/next then a @GET method can be used for a blocking take() on lets say a LinkedBlockingQueue. On the same URL you could bind a @POST method which adds data to the queue. In this case you would wrap up the functionality with the take() operation in an AsyncResponse.

@Path("/queue/next")
public class MessageQueueService {

    private static final LinkedBlockingQueue<AsyncResponse> suspendedResponses = new LinkedBlockingQueue<AsyncResponse>();

    @GET
    public void getNextMessage(@Suspend final AsyncResponse asyncResponse) {
        MessageQueueService.suspendedResponses.put(asyncResponse);
    }

    @POST
    public void putNewMessage(final String message) throws InterruptedException {
        AsyncResponse asyncResponse = suspendedResponses.take(); // note how this could also block a thread
        asyncResponse.resume(message);
    }
}

From these explanations you can also see, that the JAX-RS @Suspended mechanism is used to create an asynchronous server side task. Whether or not the same request is also executed in an asynchronous manner on the client is a whole different story.



来源:https://stackoverflow.com/questions/36214112/should-we-always-use-asynchronous-jax-rs-resources-for-mobile-backend

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!