Asynchronous I/O
for Servlet 3.0

 Jeanfrancois Arcand
 Senior Staff Engineer
 Sun Microsystems
Goal                                          JGD




• Bring Asynchronous I/O to Servlet without
  exposing low level I/O details
• New classes:
  >   ServletFuture
  >   ServletAsyncHandler
  >   ServletRequestChannel
  >   ServletResponseChannel
  >   ReadFuture
  >   WriteFuture



                                    2
ServletFuture                                 JGD




• A Future representing the result of an
  asynchronous I/O operation.
• In addition to the methods defined by the
  Future interface, a ServletFuture allows
  for the attachment of a single arbitrary
  object.
• The object can be used to associate
  application-specific data or context
  required when consuming the result of the
  I/O operation.
• This is important for cases where the
  same ServletAsyncHandler is used to
  consume the result of several I/O
  operations.
                                    3
ServletIoFuture                                  JGD




 boolean cancel(boolean mayInterruptIfRunning)

 A attachment()

 A attach(A attachment)




                                  4
ServletAsyncHandler                          JGD




• A handler for consuming the result of an
  asynchronous I/O operation.
• The asynchronous
  ServletRequestChannel.read or
  ServletResponseChannel.write defined in
  this package allow a ServletAsyncHandler
  to be specified yo consume the result of
  an asynchronous operation.
• When an operation completes the
  handler's completed method is invoked
  with the result.

                                   5
ServletAsyncHandler                            JGD




 void completed(ServletIoFuture<T,A> result)




                                   6
ServletRequestChannel                          JGD




• An asynchronous channel for read
  stream-oriented operations.
• Allow synchronous and asynchronous
  read operations
• From a Class definition, the read
  operation will convert the request body
  into an instance of that Class definition.




                                       7
ServletRequestChannel                        JGD




 <T,A> ReadFuture<T,A> read
         (java.lang.Class<T> clazz,
          A attachment,
          ServletAsyncHandler<? super T,A>
          handler)

 <T,A> ReadFuture<T,A> read
         (java.lang.Class<T> clazz,
          long timeout,
          TimeUnit unit,
          A attachment,
          ServletAsyncHandler<? super T,A>
           handler)
                                         8
Example 1: Asynchronous Read                                                    JGD




// Asynchronous Read
// The request is automatically suspended when the getChannel() is invoked.
// See Example 3 for a scenario when the request is not explicitly suspended.


ServletRequestChannel channel = servletRequest.getChannel();
ReadFuture ioFuture = channel.read(Map.class,30,TimeUnits.SECONDS, null,
         new ServletAsyncHandler<ReadFuture<Map,Void>){
               public void completed(ReadFuture<Map,Void> result){
                   Map map = result.getContent();
               }
         });




                                                               9
Example 2: Synchronous Read                                           JGD




// Synchronous Read
ServletRequestChannel channel = servletRequest.getChannel();
ReadFuture ioFuture = channel.read(Map.class);
// Or ReadFuture ioFuture = channel.read(Map.class,null,null);
ioFuture.get(30,TimeUnits.SECONDS);
Map map = ioFuture.getContent() ;




                                                                 10
Example 3: Suspendable Request                                                 JGD




// Asynchronous Read
servletRequest.suspend();
ServletRequestChannel channel = servletRequest.getChannel();
ReadFuture ioFuture = channel.read(
          Map.class,30,TimeUnits.SECONDS, servletRequest,
          new ServletAsyncHandler<ReadFuture<Map,ServletRequest>){
               public void completed(ReadFuture<Map,ServletRequest> result){
                    Map map = result.getContent();
                    result.attachment().resume();
               }
         });




                                                               11
ServletResponseChannel                 JGD




• An asynchronous channel for write
  stream-oriented operations.
• Allow synchronous and asynchronous
  write operations




                                 12
ServletResponseChannel                                  JGD




 <A> WriteFuture<Integer> write
            (Object object,
             A attachment,
             ServletAsyncHandler<Integer,A> handler)

 <A> WriteFuture<Integer> write
             (Object object,
              long timeout,
              TimeUnit unit,
              A attachment,
              ServletAsyncHandler<Integer,A> handler)



                                          13
Example 4: Asynchronous Write                                                   JGD




// Asynchronous Write
// The request is automatically suspended when the getChannel() is invoked.
// See Example 6 for a scenario when the request is not explicitly suspended.
ServletResponseChannel channel = servletResponse.getChannel();
WriteFuture ioFuture = channel.write(“Hello”,30,TimeUnits.SECONDS, null,
          new ServletAsyncHandler<WriteFuture<Integer,Void>){
               public void completed(WriteFuture<Integer,Void> result){
                   System.out.println(“Bytes Written: “ + result.get());
               }
         });




                                                                  14
Example 5: Asynchronous Write                                              JGD




// Asynchronous Write
ServletResponseChannel channel = servletResponse.getChannel();
WriteFuture ioFuture = channel.write(“Hello”,30,TimeUnits.SECONDS, null,
          new ServletAsyncHandler<WriteFuture<Integer,Void>){
               public void completed(WriteFuture<Integer,Void> result){
                   System.out.println(“Bytes Written: “ + result.get());
               }
         });




                                                                  15
Example 6: Synchronous Write                                     JGD




// Asynchronous Write
ServletResponseChannel channel = servletResponse.getChannel();
WriteIoFuture ioFuture = channel.write(“Hello”);
ioFuture.get(30,TimeUnits.SECONDS);




                                                           16
Example 2: Suspendable Request                                                         JGD




// Asynchronous Read
servletRequest.suspend();
ServletResponseChannel channel = servletResponse.getChannel();
WriteIoFuture ioFuture = channel.write(
 “Hello”,30,TimeUnits.SECONDS, servletRequest, new
           ServletAsynchronousIoHandler<WriteIoFuture<Integer,ServletRequest>){
                public void completed(WriteIoFuture<Integer,ServletRequest> result){
                    result.attachment().resume();
                }
         });




                                                                17
Summary                               JGD




• Simple API.
• No buffering of data
• API can be used synchronously and
  asynchronously.
• Easy to implement.




                                 18
jeanfrancois.arcand@sun.com

Servlet Async I/O Proposal (NIO.2)

  • 1.
    Asynchronous I/O for Servlet3.0 Jeanfrancois Arcand Senior Staff Engineer Sun Microsystems
  • 2.
    Goal JGD • Bring Asynchronous I/O to Servlet without exposing low level I/O details • New classes: > ServletFuture > ServletAsyncHandler > ServletRequestChannel > ServletResponseChannel > ReadFuture > WriteFuture 2
  • 3.
    ServletFuture JGD • A Future representing the result of an asynchronous I/O operation. • In addition to the methods defined by the Future interface, a ServletFuture allows for the attachment of a single arbitrary object. • The object can be used to associate application-specific data or context required when consuming the result of the I/O operation. • This is important for cases where the same ServletAsyncHandler is used to consume the result of several I/O operations. 3
  • 4.
    ServletIoFuture JGD boolean cancel(boolean mayInterruptIfRunning) A attachment() A attach(A attachment) 4
  • 5.
    ServletAsyncHandler JGD • A handler for consuming the result of an asynchronous I/O operation. • The asynchronous ServletRequestChannel.read or ServletResponseChannel.write defined in this package allow a ServletAsyncHandler to be specified yo consume the result of an asynchronous operation. • When an operation completes the handler's completed method is invoked with the result. 5
  • 6.
    ServletAsyncHandler JGD void completed(ServletIoFuture<T,A> result) 6
  • 7.
    ServletRequestChannel JGD • An asynchronous channel for read stream-oriented operations. • Allow synchronous and asynchronous read operations • From a Class definition, the read operation will convert the request body into an instance of that Class definition. 7
  • 8.
    ServletRequestChannel JGD <T,A> ReadFuture<T,A> read (java.lang.Class<T> clazz, A attachment, ServletAsyncHandler<? super T,A> handler) <T,A> ReadFuture<T,A> read (java.lang.Class<T> clazz, long timeout, TimeUnit unit, A attachment, ServletAsyncHandler<? super T,A> handler) 8
  • 9.
    Example 1: AsynchronousRead JGD // Asynchronous Read // The request is automatically suspended when the getChannel() is invoked. // See Example 3 for a scenario when the request is not explicitly suspended. ServletRequestChannel channel = servletRequest.getChannel(); ReadFuture ioFuture = channel.read(Map.class,30,TimeUnits.SECONDS, null, new ServletAsyncHandler<ReadFuture<Map,Void>){ public void completed(ReadFuture<Map,Void> result){ Map map = result.getContent(); } }); 9
  • 10.
    Example 2: SynchronousRead JGD // Synchronous Read ServletRequestChannel channel = servletRequest.getChannel(); ReadFuture ioFuture = channel.read(Map.class); // Or ReadFuture ioFuture = channel.read(Map.class,null,null); ioFuture.get(30,TimeUnits.SECONDS); Map map = ioFuture.getContent() ; 10
  • 11.
    Example 3: SuspendableRequest JGD // Asynchronous Read servletRequest.suspend(); ServletRequestChannel channel = servletRequest.getChannel(); ReadFuture ioFuture = channel.read( Map.class,30,TimeUnits.SECONDS, servletRequest, new ServletAsyncHandler<ReadFuture<Map,ServletRequest>){ public void completed(ReadFuture<Map,ServletRequest> result){ Map map = result.getContent(); result.attachment().resume(); } }); 11
  • 12.
    ServletResponseChannel JGD • An asynchronous channel for write stream-oriented operations. • Allow synchronous and asynchronous write operations 12
  • 13.
    ServletResponseChannel JGD <A> WriteFuture<Integer> write (Object object, A attachment, ServletAsyncHandler<Integer,A> handler) <A> WriteFuture<Integer> write (Object object, long timeout, TimeUnit unit, A attachment, ServletAsyncHandler<Integer,A> handler) 13
  • 14.
    Example 4: AsynchronousWrite JGD // Asynchronous Write // The request is automatically suspended when the getChannel() is invoked. // See Example 6 for a scenario when the request is not explicitly suspended. ServletResponseChannel channel = servletResponse.getChannel(); WriteFuture ioFuture = channel.write(“Hello”,30,TimeUnits.SECONDS, null, new ServletAsyncHandler<WriteFuture<Integer,Void>){ public void completed(WriteFuture<Integer,Void> result){ System.out.println(“Bytes Written: “ + result.get()); } }); 14
  • 15.
    Example 5: AsynchronousWrite JGD // Asynchronous Write ServletResponseChannel channel = servletResponse.getChannel(); WriteFuture ioFuture = channel.write(“Hello”,30,TimeUnits.SECONDS, null, new ServletAsyncHandler<WriteFuture<Integer,Void>){ public void completed(WriteFuture<Integer,Void> result){ System.out.println(“Bytes Written: “ + result.get()); } }); 15
  • 16.
    Example 6: SynchronousWrite JGD // Asynchronous Write ServletResponseChannel channel = servletResponse.getChannel(); WriteIoFuture ioFuture = channel.write(“Hello”); ioFuture.get(30,TimeUnits.SECONDS); 16
  • 17.
    Example 2: SuspendableRequest JGD // Asynchronous Read servletRequest.suspend(); ServletResponseChannel channel = servletResponse.getChannel(); WriteIoFuture ioFuture = channel.write( “Hello”,30,TimeUnits.SECONDS, servletRequest, new ServletAsynchronousIoHandler<WriteIoFuture<Integer,ServletRequest>){ public void completed(WriteIoFuture<Integer,ServletRequest> result){ result.attachment().resume(); } }); 17
  • 18.
    Summary JGD • Simple API. • No buffering of data • API can be used synchronously and asynchronously. • Easy to implement. 18
  • 19.