jsr340-experts@servlet-spec.java.net

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

From: Oleksiy Stashok <oleksiy.stashok_at_oracle.com>
Date: Tue, 10 Apr 2012 16:23:42 +0200

Hi Greg,

On 04/02/2012 02:59 PM, Greg Wilkins wrote:
> The proposal that you make is essentially the NIO.2 style, where the
> buffer is passed to the IO layer and is asynchronously flushed and
> once it is done you can either ask if it is complete or have a
> callback telling you that it is complete.
Right, but IMO we shouldn't bypass servlet I/O layer, so we still have
to consider that write(ByteBuffer) may just copy ByteBuffer into servlet
internal buffer (for sure it depends on servlet buffer size) and you
still have to call flush() to make sure the ByteBuffer has been sent.

> However, your API does have some benefits over NIO.2 - it allows a
> poll to test for completion before committing to register a callback
> handler, which may avoid some of the expense of callback.
>
> I think we could build on your approach, but give it more NIO.2 syntax:
>
> interface IOFuture extends Future<Integer>
> {
> setCompletionHandler(CompletionHandler<Integer,Object> handler);
> }
>
> Write operations could then return an IOFuture which could be queried
> for completion (equivalent to your canWrite call) or have a completion
> handler registered (equivalent to your os.notifyCanWrite).
May be we can make flush() method to return such a IOFuture?
---------------------
IOFuture flush();
---------------------

Thanks.

WBR,
Alexey.

> Eitherway, I agree with your basic premise - that we pass the entire
> application buffer to the IOLayer and let it do as much work as
> possible without copying - and then communicate back to the
> application when the previous operation is complete and the buffer can
> be reused.
>
> cheers
>
>
>
>
>
>
>
> On 2 April 2012 19:06, Oleksiy Stashok<oleksiy.stashok_at_oracle.com> wrote:
>> 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.
>>