users@servlet-spec.java.net

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

From: Oleksiy Stashok <oleksiy.stashok_at_oracle.com>
Date: Mon, 02 Apr 2012 11:06:48 +0200

Hi Greg,

On 04/02/2012 07:10 AM, Greg Wilkins wrote:
> On 31 March 2012 05:46, Remy Maucherat<rmaucher_at_redhat.com> wrote:
>> On Fri, 2012-03-30 at 19:23 +0200, Oleksiy Stashok wrote:
>>> Once we don't have integer parameter neither in canWrite nor in
>>> notifyCanWrite, AFAIU we can guarantee that if canWrite() returned
>>> true - next "write" method call (despite the size of the passed data)
>>> will not block.
>> That's what I am doing (and it works). It is necessary IMO since the for
>> example char methods of the writer are relatively unpredictable in terms
>> of output size. The downside is the resource use, but as you mention,
>> regardless of the technique employed, the memory is used until the bytes
>> are written.
> There is a big difference between the application holding the
> reference and the IO layer holding the reference. The application
> layer can know if the buffer is shareable or not.
>
> Say I have 100,000 connections and I want to write the same large
> string to all of them, then if the application holds the reference,
> then it converts the ig string to a ByteBuffer it can pass a
> buffer.asReadOnly() to each connection and there is no copy. If the
> IO layer holds the reference, then it will have to copy it (all of it
> or just the remainder), then we get 100,000 copies of the large
> string!
I agree, but it's not what I tried to propose. I proposed to introduce
separate (Servlet)OutputStream.write(ByteBuffer) method, which will be
copy-free. It's going to complicate the ByteBuffer re-usage, but IMO
it's worth it.

Here is the sample I gave in the prev. email:
-------------------------------------------------------------------
if (os.canWrite()) {
         os.write(appBuffer);
}

os.flush(); <---------- flush servlet buffer

if (os.canWrite()) {
     (1) <---------------- starting here we can reuse appBuffer
} else {
         os.notifyCanWrite(new WriteListener() {
                     void onWritePossible() {
                                 (2) <---------------- starting here we
can reuse appBuffer
                     }
         }
}
-------------------------------------------------------------------

WBR,
Oleksiy.