jsr340-experts@servlet-spec.java.net

[jsr340-experts] Re: Servlet 3.1 EDR updated draft

From: Remy Maucherat <rmaucher_at_redhat.com>
Date: Thu, 31 May 2012 10:47:59 +0200

On Thu, 2012-05-31 at 10:19 +0200, Greg Wilkins wrote:
> For example if servletOutputStream.canWrite() returns true, then I
> immediately do
>
> out.write(verylargearrayofbytes);
>
> then the signature of write has no way to communicate a partial write
> - thus a full write must be done (which is fine). But if that array
> is too large to be written without blocking then there are several
> ways in which this can be done:
>
> a) The write call will block until all data is written. This would
> give us a kind of hybrid mode where small writes could be done
> asynchronously, but large ones may block. Benefit of this approach is
> that it is simple to implement and simple to use without any complex
> buffering.
>
> b) The write will send as much as it can and then copy the unwritten
> data and return immediately. It will flush the unwritten data
> asynchronously and while doing so canWrite will be false and any
> writelistener will be called when the write completes. This gives
> nonBlocking behaviour, but at the cost of a potential big copy.
>
> c) The write will send as much as it can and then return immediately
> but keep a reference to the data array. It will flush the unwritten
> data asynchronously and while doing so CanWrite will be false and any
> writelisteners will be called when the write completes. This gives
> nonBlocking behaviour, but the caller must not change the passed byte
> array until such time as they are told the output stream is writeable
> again. However it avoids a large copy. This mode is kind of like
> NIO.2 style, but without ByteBuffers.

The behavior has been described previously: the call will not block, and
the container will handle the rest of your bytes for you, so that's b).
The "big copy" argument is actually inaccurate, since with Servlets and
their buffering, possible filtering, compression, SSL, the regular
blocking IO will never do a zero copy write either.

> Also I'm not exactly sure how often WriteListener.onWritePossible is
> called? Is it called after every write? ie if I write 1 byte and
> there is not blocking will it be called?

It will be called once, Rajiv clarified it. Presumably, after canWrite
has actually been called and returned false (otherwise, the Servlet
can't really know about the state).

> Finally, how does asynchronous mode interact with
> Response.resetBuffer, Response.setBufferSize etc. When writing
> nonBlocking, can we write data < the buffer size and then reset the
> buffer?

What had been said previously was that the IO extensions would respect
the existing Servlet API buffering. Of course, that was when async for
reader/writer was still present.

All this could be present in the spec document, of course, for better
understanding.

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