jsr340-experts@servlet-spec.java.net

[jsr340-experts] Re: Do we really need async IO

From: Remy Maucherat <rmaucher_at_redhat.com>
Date: Fri, 09 Mar 2012 09:14:30 +0100

On Fri, 2012-03-09 at 15:56 +1100, Greg Wilkins wrote:
> On 8 March 2012 20:25, Remy Maucherat <rmaucher_at_redhat.com> wrote:
> > On Thu, 2012-03-08 at 16:45 +1100, Greg Wilkins wrote:
> >> No, the servlet has to check each write to see if all the passed bytes
> >> were written, and if not, then give up the thread and wait for the
> >> canWrite callback.
> >
> > It should be obvious that most small writes are going to be done
> > immediately, so the boolean flag stays the same as true, and the
> > application can continue writing (= zero cost).
>
> Asynchronous IO APIs should not be used in this way. They are not
> intended for code like:
>
> asyncStream.write("<h1>");
> asyncStream.write(mytitle);
> asyncStream.write("/<h1>");

Ok, ok, I get it, I'm not holding it right.

> Because any of those writes could return 0 or < all bytes written and
> the application code would be unworkable.
> Instead, these writes should be to a buffer and then the entire buffer
> can be written via the asyncIO.
>
> If for some reason, you really do have multiple short contents to
> write, then that could be handled with a gather write:
>
> public void write(ByteBuffer...
> buffer,CompletionHandler<Boolean,AsyncContext> handler)
> {
> }
>
> Thus the completion handler would only be called back after all the
> short writes had been done, not after each of them.
>
> Also note that there is no requirement that the call back be done in a
> different thread. If the write manages to write all the content, then
> it could directly call the completion handler.

I think it is legitimate if the user does a highly interactive
bidirectional protocol using the upgraded API (or the Servlet 3.1 IO on
top of HTTP). I would like the user to be able to do any protocol
without ill effects actually. It is fine if there's a small baseline
cost for not doing a server with raw sockets, obviously, but that's
about it.

> > Note: I think this was already discussed months ago when hesitating over
> > the style of the API, and Rajiv proposed the two main options (blocking
> > IO with flags, or NIO2 style). Did I miss something ?
>
> I think there was a discussion about if we should directly use the
> NIO2 API's directly. There was some concern about how efficient they
> were because their style requires read buffers to be allocated when a
> read is scheduled rather than when it occurs.
>
> I've used them a bit more since then and have warmed to the style
> somewhat. They certainly are simpler to use that traditional style
> async IO.
>
> I just really think we need to think REALLY hard before we go off an
> invent yet another IO style for use with just servlets

Well, this is an "invention" I made on my own a few years ago, because
it did look logical, and I doubt Rajiv copied from it. What could keep
the speed benefits of the blocking IO API while allowing not blocking
and implementing generic flexible IO ? My async IO implementation is
today in JBoss AS 6 (and 7) if you want to look at it (unfortunately it
is not fully integrated with the Servlet API, it is more like the
upgrade support - although it remains HTTP).

For NIO 2, the initial results show it has low memory use and no special
buffering requirements, so I don't see it a problem. It looks like
java.io has no future.

Your proposal is functionally complete more or less so it does not look
unacceptable to me, although I strongly prefer the one from Rajiv. I
thought, from the feedback that was posted until now, that everyone was
fine with Rajiv's drafts, but apparently it is not the case anymore. So
let's see more feedback.

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