users@servlet-spec.java.net

[servlet-spec users] [jsr340-experts] Re: Async IO and Upgrade proposal updated

From: Greg Wilkins <gregw_at_intalio.com>
Date: Tue, 3 Apr 2012 09:37:18 +1000

On 3 April 2012 01:06, Remy Maucherat <rmaucher_at_redhat.com> wrote:

> What does "no async IO" means ? Is it Servlet 3.0 with no changes ?

It means that I'm not 100% convinced that we still need async IO. If
websocket and SPDY are build into the container and exposed via APIs
designed in other JSRs, then is there really still a need for async IO
in 3.1? I don't know? Do we have any users that are actively
asking for it?


> So probably adding a separate API with ByteBuffer (with support for
> mapped ones in mind) is possible, but I wouldn't have it replace Rajiv's
> proposal, I don't consider it does the same thing, it's more a
> complement.

I see several benefits of an API based on ByteBuffers:

 + Ability to pass direct buffers and file mapped buffers
 + Each buffer has a position/limit pointers, which allows the app and
IO layer to communicate about how much content has been consumed.
 + They work well with other libraries (eg SSLEngine if encryption is needed)
 + They can be easily created and filled using NIO / NIO.2 code locally
 + The wrap mechanism is simple and cheap so byte arrays can also be handled.

But I agree a ByteBuffer API vs an byte[] API are probably different
things intended for different use-cases.
I'm not opposed to support either one or both, so long as we do the
analysis to make sure that we support the use-cases that we need to
support.

I believe that async IO is entirely unsuitable for IO style like:

   out.write("<h1>".getBytes());
   out.write(greeting.getBytes());
   out.write("</h1>".getBytes());
   out.flush();

Because any of those operations can fail to complete/need a callback
etc. With async IO, you tend to prepare an entire message or
chunk and then write it, so having a buffer inside the IO layer that
accumulates content (like we do with current OutputStream and Writers)
is not really needed.

If this API is to be used to implement protocols like websocket, then
framing data will be a common operation, so instead of offering an IO
layer that accumulates small writes, a gather API may be more
appropriate:

  ByteBuffer data = getSomeData()
  ByteBuffer header = buildWebSocketHeader(data.remaining());
  Future<Integer> complete = out.write(header,data);

I think we are lacking the use-cases to really say which style of API
is going to be best.