jsr340-experts@servlet-spec.java.net

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

From: Remy Maucherat <rmaucher_at_redhat.com>
Date: Wed, 28 Mar 2012 17:11:53 +0200

On Thu, 2012-03-29 at 01:23 +1100, Greg Wilkins wrote:
> > Am not fully sure what you are suggesting here. We could use a ByteBuffer
> > instead
> > and provide a write(ByteBuffer) if that helps. Is that what you mean? But
> > you are still
> > buffering no matter what IMHO.
>
> A ByteBuffer helps a little bit, because it gives the caller a
> position index to help remember how much has been written, but I agree
> it is not the solution.
>
>
> I see two ways to resolve this:
>
> a) remove the concept of how many bytes can be written without
> blocking from the API. Just have a call back that says more data can
> be written and return the bytes written from every call. This still
> requires the application to track the partially written content, but
> at least it removes the requirement to have internal buffering in the
> implementation.

It is probably a good thing then that it is not what should be done ...
Of course, you probably know it, the only purpose of this is to make b)
look simpler I suppose.

I use blocking semantics, but any bytes that cannot be immediately
written are buffered by the container, while the flag that indicates
that writing can continue is of course flipped. For whatever reason, you
apparently believe the possible cost of copying these bytes somewhere is
higher than a thread pool trip + container callback *on every single
write*. That is clearly not the case, there's no need to ask a NIO 2
expert to know that ... The NIO 2 approach also has a glitch since the
application buffer is no longer available to it until writing is
complete, which is not the case for the other solution (it is ok to
reuse it as soon as write returns), making buffer management likely
easier. The memory use is actually the same for the two solutions: the
user data will be managed by the container until it is fully written.

If you think we should cover the efficient file serving scenario, it
could be done using its own API [I have added a response.sendFile(String
path, String absolutePath, long start, long end) in my implementation,
with use of absolutePath getting additional security checks]. I'm fine
with that.

Personally, I also don't see any big benefit in knowing an amount of
bytes that can be written vs a simple boolean flag, but of course I can
provide a conservative estimate (the socket always has a dedicated
buffer attached to it), which is why I am fine with Rajiv's proposal.

> b) go to something like the Java7 NIO2 where you call
> write(buffer,handler) and the handler is called back once the entire
> buffer is written. No chunks, no copying, direct buffers! Any
> luck getting the guys that designed NIO2 to come chat to us about
> this?

If this is the chosen solution, I'll have the benchmarks ready on
release day :)

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