410 likes | 573 Views
Think Async. Embrace and Get Addicted to the Asynchronicity of Java SE and EE. Masoud Kalali, Software Engineer, ORACLE, @ MasoudKalal. Program Agenda. 1. 2. 3. 4. 5. 6. 7. Introduction Why to think Async A simple case of using Async JMS (2.0) Async Servlet Async JAX-RS
E N D
Think Async Embrace and Get Addicted to the Asynchronicity of Java SE and EE Masoud Kalali, Software Engineer, ORACLE, @MasoudKalal
Program Agenda 1 2 3 4 5 6 7 Introduction Why to think Async A simple case of using Async JMS (2.0) Async Servlet Async JAX-RS Async EJBs
Speakers Masoud Kalali Software engineer, author, blogger Long advocate of GlassFish and Java EE Tweets at @MasoudKalali
Why to think Async? • To better model what we develop for • To further decouple • Ease of administration • Ease of tuning • Ease of maintenance • Improve consumers experience • An API consumer • A direct GUI for human use • etc.
Java EE And ASynchronicity • Long present JMS • To be used almost everywhere • Servlet 3.0/ 3.1 • Asynchronous Servlets • None blocking IO • JAX-RS 2.0 • Server side • Client side • Asynchronous Session Beans • Server side • Client side
A simple asynchronous nourished use case Client Async Servlet Query Processor 1 3 4…. 2.1 JMS Queue 8…. Query Requests in JMS 2 MDB JMS Queue Cache 7…. 6…. 5…. Consume result chunks and send it back via AsyncContext ID, AsyncContext Chunks of Query results 1
A simple asynchronous nourished use case More details of the Messaging components • One JMS queue for sending the query requests • One JMS queue which will get chunks of query results • An MDB which will consume the query result messages • Uses the cache and the id in the message to pick up the right AsyncContext • As long as the message does not say it is done it will not conclude the response • Complete the response when JMS message implies
A simple asynchronous nourished use case More details of the Servlet components • Asynchronous Servlet receiving the requests • Caching the AsynContext and a query Id • Sending the Query message to the JMS queue • Including the query Id • Leave it to the MDB to update the response • Have a AsyncListener to send proper response if timeouts
A simple asynchronous nourished use case Some basics on the client side • A browser • Can be • A SSE client • A COMET, Long Polling request
JMS (2.0) A brief overview
JMS: A brief overview I • Broker • Message • Queue • Producers • Consumers • Topic • Publishers • Subscribers
JMS 2.0: A brief overview: • Multiple Consumers Allowed on the Same Topic Subscription • Delivery Delay • Sending Messages Asynchronously • Send the message and get callback when it is acknowledged by broker • JMSXDeliveryCount message property No longer optional • Standard MDB Configuration Properties as part of @MessageDriven • destinationType • subscriptionDurability • acknowledgeMode • subscriptionName • ...
Servlet 3.0 Asynchronous servlet
Servlet 3.0 Asynchronicity • Why we want it • More throughput • Better architecture mapping • How it works • @WebServlet.asyncSupported, async-supported in XML config! • AsyncContext • AsyncListener
Servlet 3.0 Asynchronicity: AsyncContext • Adding listeners • Doing request dispatching • Accessing ServletRequest • Accessing ServletResponse • Concluding the request/response • Setting, getting timeouts
Servlet 3.0 Asynchronicity : AsyncListener • Get callback on important events on an async request processing • onComplete(AsyncEventasyncEvent) • onError(AsyncEventasyncEvent) • onStartAsync(AsyncEventasyncEvent) • onTimeout(AsyncEventasyncEvent)
Servlet 3.0 Asynchronicity : A little bit of code @WebServlet(asyncSupported = true, value = ”/query-servlet") public class QueryServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id=...; cache.put(id,request.startAsync()); sendQueryMessage(id, request); } }
Servlet 3.1 Non-blocking IO
Servlet 3.1: Non-Blocking IO • Why do we want it? • How does it work? • ReadListener: To read inbound data when available • WriteListener: To write data when possible • Changes in ServletOutputStream • isReady() • setWriteListener(…) • Changes in ServletInputStream • isFinished() • isReady() • setReadListener(…)
Servlet 3.1: Non-Blocking IO: ReadListener • To get callbacks on ServletInputStream events • onDataAvailable • OnAllDataRead • onError
Servlet 3.1: Non-Blocking IO: WriteListener • To get notified on ServletOutputStreamevents • onError • onWritePossible
Asyncronicity in JAX-RS 2.0 • Why would we need it? • How does it work? • @Asynchronous • ExecutionContext for programmatic decision to do or not to do async • AsyncResponse • @Suspended • CompletionCallback • ConnectionCallbck
Asyncronicity in JAX-RS 2.0: Server-side I How to mark a resource as Asynchronous • On the serverside: • @Asynchronous: Annotate a sub-resource as Asynchronous • AsyncResponse: Provides results an actions on the running request • setting timeout • registering callbacks • resume, cancel suspended request processing • updating the response • @Suspended: To inject a suspended AsyncResponse into a sub-resource parameter
Asyncronicity in JAX-RS 2.0: Server-side simple code Server Code: @Path("/api/query") public class MyResource { @Context private ExecutionContextctx; @GET @Produce(“application/json”) @Asynchronous @Path(“api/matching-query”) public void prepMatchingQueryResult(@Suspended AsyncResponsear, @QueryParam String p1… ) { executor.submit( new Runnable() { public void run() { JsonObjectresponse = getQueryResult(p1…); ctx.resume(response); //container thread picks up and continue } }); ctx.suspend(); // Suspend connection and return } … }
Asyncronicity in JAX-RS 2.0: client-side simple code Client-Side with future Future<JsonObject> future = client. target(“/api/query/matching-query”).queryParam(...).request().async().get(JsonObject.class); try { JsonObjectqueryResult = future.get(30, TimeUnit.SECONDS); } catch (TimeoutException ex) { // }
Asyncronicity in JAX-RS 2.0: client-side simple code Client-Side with callback Future<JsonObject> future = client. target(“/api/query/matching-query”). queryParam(...).request().async().get(new InvocationCallback<JsonObject>() { @Override public void completed(JsonObject response) { //Invocation happens and some response is back (404, 200, etc.) } @Override public void failed(Throwablethrowable) { //Invocation fails (client side) } });
Asyncronicity in JAX-RS 2.0: Server-side II CompletionCallback • Single method interface • void onComplete(Throwable t) • signal completion of serving a request
Asyncronicity in JAX-RS 2.0: Server-side III ConnectionCallback • Single method interface • void onDisconnect(AsyncResponse disconnected) • signals interruption in client connection before completion
Asynchronous And long running jobs in REST Don’t keep unnecessary resources for where not needed! • Multi-step long running jobs not suitable with JAX-RS Async • Send 202 where response is not ready with Location header • Intelligent enough client can query the resource Locationwith the given Retry-After header
EJB 3.1 Asynchronicityin Session Beans
Asynchronicity in EJB 3.1 • Works on session beans • fire and forget • Using Future<V> to decide on completion • AsyncResult as container specific vehicle • Passes the result to Future<V> • As simple as using @Asynchronous on method/bean • Method should return Future<V> • Client can poll the future for Completion
Asynchronicity in EJB 3.1: Simple code sample Server-side code @Stateless public class QueryProcessor { @Asynchronous public Future<QueryResult> processQuery(QueryCritcrit){ try{ QueryResultresult= prepQueryResult(crit); return new AsyncResult(result); }catch(Exception e){ //handle return new AsyncResult(FAILURE_RESULT); } }}
Asynchronicity in EJB 3.1: Simple code sample cliet-side code @Inject QueryProcessorqueryProcessor; private JsonObjectprepareQueryResult(String... params){ QueryCritcrit = new QueryCrit(params) Future<QueryResult> result=queryProcessor.prepQueryResult(crit); //poll the Future.. There is no callback here... } }
Java EE 7 and SSE Asynchronicity in SSE
Server-Sent Events • HTML 5 component • Client subscribe to event source • Unidirectional channel between server and client • Events can be streamed from server to client when happens • Connection stays open • event handling on client side • onMessage • onError • etc. • Subscription resuming
Server-Sent Events • Can be developed using a plain Servlet • use the right media type • use the correct message format • Jersey provides support not JAX-RS yet • Server side to turn a JAX-RS endpoint to SSE broadcaster • Client side to subscribe and consume SS events
Resources • RESTful Services Patterns and best practices By Bhakti Mehta • Bhakti’s blog: https://www.java.net/blog/bhaktimehta • Book’s sample codes: • CCL photos used in slides: • https://www.flickr.com/photos/treehouse1977/2892417805/ • https://www.flickr.com/photos/treehouse1977/2892417805/ • https://www.flickr.com/photos/essjay/165928100/ • https://www.flickr.com/photos/jforth/4413370462/ • https://www.flickr.com/photos/sakalak/8737872379/ • https://www.flickr.com/photos/jbparrott/8980026600 • https://www.flickr.com/photos/pentadact/36593493/ • https://www.flickr.com/photos/jasohill/4442279347/ • https://www.flickr.com/photos/mdsharpe/5075953655 • https://www.flickr.com/photos/chuqvr/8329512894/