Catching up on this thread. Please see comments in-line -
On 4/3/12 7:48 AM, Remy Maucherat wrote:
> 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
I think we should start with the API that we have with some tweaks that
we need as discussed in email but we should include the API as you state
in a) above.
>
> 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)
I think we need to add the capability in general and not tie it with
only upgrade. I think that as someone (Remy you?) pointed out that
frameworks can leverage it to get better performance.
Having said that I think we should start with the changes I suggested in
the email earlier on for the canWrite and write methods. We can think a
little more about adding a write(ByteBuffer) but am not convinced we
need that in there as yet. I will update the proposal on the wiki and
also update the spec document and send out another version to the alias
as soon as I can.
- Rajiv
> (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 ...
>