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);
}