jsr340-experts@servlet-spec.java.net

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

From: Remy Maucherat <rmaucher_at_redhat.com>
Date: Tue, 03 Apr 2012 16:48:25 +0200

On Tue, 2012-04-03 at 09:37 +1000, Greg Wilkins wrote:
> 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?

There are proposals for two async APIs at the moment:
a) an API to extend the HTTP Servlet IO
b) an API for the upgraded HTTP connection IO, which would need to
support a variety of protocols that would be implemented in the
application space (like websockets); since this one should stay generic,
support highly interactive bidirectional transports and should scale as
well as possible, I remain convinced something like Rajiv's API is the
most appropriate

So I am ok examining that a) doesn't need async IO, since for example we
never did non blocking IO for HTTP Servlets. OTOH, with each release, I
noticed people complaining there was no non blocking IO included. So I
think the capability must now be there (as async IO), but it could be
enough to do it in b) (people would do the media stuff in websockets,
for example, and doing classic webpages would work well enough with
blocking). Except that the container infrastructure to do b) is very
similar to the one to do a), since the upgrade process is essentially
about not using any HTTP transfer encoding. I would be ok to not do a)
if b) is done if it can be demonstrated the impl/spec cost is going to
be very large, but I don't think that's the case.

> > 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.

I believe frameworks have an opportunity to take advantage of the API,
but obviously the hello world servlet is not a very good use case.

> 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.

In many cases, blocking IO works too. But ...

-- 
Remy Maucherat <rmaucher_at_redhat.com>
Red Hat Inc