jsr340-experts@servlet-spec.java.net

[jsr340-experts] Re: [servlet-spec users] Re: setWriteListener setReadListener

From: Rémy Maucherat <rmaucher_at_redhat.com>
Date: Tue, 21 May 2013 10:07:47 +0200

On 05/21/2013 01:42 AM, Greg Wilkins wrote:
>
> Working through the state machine before, I come to the conclusion
> that autoblocking is over complex and provides a semantic that we
> don't want to provide.
>
> With normal blocking IO, we don't provide any mutual exclusion and the
> application is responsible for synchronisation at a higher level.
>
> However with autoblocking, a write that should be autoblocked can
> happen before the previous asynchronous write is complete. The
> application cannot delay the autoblocking write until the previous
> request is complete because it has no way of knowing when it is
> complete, since if it calls isReady() that will make the next write an
> async write rather than an autoblocking one. Thus to implement
> autoblocking we have to be prepared to block a write until such time
> as the previous asynchronous write completes - which is a semantic in
> advance of what we offer for normal blocking. What if we get
> multiple simultaneous autoblock writes? Do we have to queue them in
> the order they were received and unblock each as the previous write
> completes? This is the makings of a dangerous infinite queue!
>
> So on reflection, I think that we should not provide autoblocking and
> that once we have switched to asynchronous mode it is an ISE to call
> write without a prior call to isReady() that returns true or a
> onWritePossible() callback.
>
> The simplified state machine that results is:
>
> ACTION OPEN ASYNC READY PENDING UNREADY
> -------------------------------------------------------------------------------------
> setWriteListener() READY->owp ise ise ise ise
> write() OPEN ise PENDING wpe wpe
> isReady() ise READY:true READY:true UNREADY:false
> UNREADY:false
> write completed - - - ASYNC READY->owp
>
Yes, it is simpler. But then not doing it makes some (bad, IMO) use
cases much harder.

About concurrent writes, it is never possible, there is no queue needed.
If the user uses async writes, he knows it, and has to wait for owp to
continue writing. Anything else is illegal. In blocking mode, the
container thread blocks, it is then up to the user to not do any
concurrent write since it is illegal too (as with a regular servlet).
Overall, it's similar to NIO2 on sockets for the general behavior: any
write can be blocking or async, but concurrency is never allowed.

Rémy