users@servlet-spec.java.net

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

From: Greg Wilkins <gregw_at_intalio.com>
Date: Thu, 31 May 2012 11:13:15 +0200

On 31 May 2012 10:47, Remy Maucherat <rmaucher_at_redhat.com> wrote:
>
> 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.

There is a big difference in buffering.

Currently if someone does write(OneGigByteArray), then a container is
able to use arbitrary sized buffers to send that. Ie I can use a few
16k buffers to slice off bits of the 1G and encrypt as SSL etc. and
send that 1G. Ie the container is in control of it's memory
footprint.

But with what you propose, the container will have to buffer
OneGigMinusALittleBit. The container is now out of control of it's
memory footprint and effectively is doubling down on any allocations
the application makes!

I think it far better to use option c). where the container does not
copy the passed byte arrays and just keeps a reference to them. In
many cases they will be written immediately (either into a buffer,
into ssl or onto the network) and the buffer can be reused
immediately. But in the case that canWrite returns false after a
write, then the passed byte array should not be changed until canWrite
is true again. This gives pretty much the same semantics, but
allowing the container to control its memory footprint.



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

So if the app does not call canWrite, but keeps calling write(bytes)
write(bytes) write(bytes), then the container will have to infinitely
buffer that data?

Perhaps we need to say that once we are in async mode then canWrite
must be called between every write. If it is not called, then write
will throw ISE.


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

Lots has been said previously one way or the other. The spec document
MUST say exactly what the behaviour is.


cheers