users@jersey.java.net

[Jersey] JAX-RS 2 suspended responses and Grizzly executors

From: algermissen1971 <algermissen1971_at_mac.com>
Date: Sun, 23 Feb 2014 10:44:54 +0100

Hi,

I am developing a purely Grizzly-based JAX-RS 2 application, using the JAX-RS 2 async features to talk to a database (Cassandra) upstream.

The database query is done asynchronously and I add a listener to the future returned by the Cassandra API. Adding the listener requires passing an executor.

I am enterely unsure what the idiomatic way is in Grizzly to obtain / create a suitable executor.

The way I did it below is taken from a Jersey-example [1] but I wonder whether that is too naive.

Is there a nore production syste appropriate way of creating or obtaining an executor for handling the AsyncResponse once the futures return?

Jan


[1] https://github.com/jersey/jersey/blob/master/examples/server-async-standalone/webapp/src/main/java/org/glassfish/jersey/examples/server/async/LongRunningEchoResource.java

Jan
class UserResource {

    private static final ExecutorService TASK_EXECUTOR = Executors.newCachedThreadPool();

   // ...

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public void getUser(@QueryParam("userId") String userId, @Suspended final AsyncResponse ar) {
  
      ar.setTimeoutHandler(new TimeoutHandler() {
            public void handleTimeout(AsyncResponse ar) {
                ar.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE).entity(
                        "Operation timed out -- please try again").build());
            }
        });
        ar.setTimeout(15, TimeUnit.SECONDS);

       // Invoke Cassandra async query execution and add Listener to future
        final ResultSetFuture f = session.executeAsync("select user_id, name from users where user_id = " + userId);
        f.addListener(new Runnable() {
            public void run() {
                ResultSet rows;
                try {
                    rows = f.get();
                } catch (Exception e) {
                    ar.resume(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Internal server error").build());
                    return;
                }
                Row row = rows.one();
                if(row == null) {
                    ar.resume(Response.status(Response.Status.NOT_FOUND).entity("User not found"));
                    return;
                }
                String userId = row.getString("user_id");
                String name = row.getString("name");
                ar.resume(Response.status(Response.Status.OK).entity( "User: " + name ).build());
            }
        }, TASK_EXECUTOR);

}