users@servlet-spec.java.net

[servlet-spec users] [jsr340-experts] Re: Re: Re: NIO specification clarification

From: Rémy Maucherat <rmaucher_at_redhat.com>
Date: Mon, 29 Apr 2013 11:51:09 +0200

On 04/29/2013 09:43 AM, Mark Thomas wrote:
> I think the problem is a little more difficult than that.
>
> WebSocket requires a call-back (to user code) once the async send has
> completed. Consider the following:
>
> - Large async write
> (Handled inside container - no user code)
> - Container thread reading data in user code triggers a blocking write
> (async above still on-going)
> - Large sync write
> (Auto-blocking starts, container thread blocked)
> - Async write completes triggering a call back on a container thread to
> user code
>
> At this point you have two container threads in user code. One is
> blocked but the need for two threads triggers essentially the same
> complications as my current solution (all two threads, one for read,
> one for write) and adds the complexity of auto-blocking.
>
> One way around this would be to delay the call-back from the async write
> until the sync write has completed. That solves the problem of multiple
> threads in user code but doesn't remove the requirement for multiple
> threads in container code.
Looking back at the details, in particular in the "concurrency"
discussion on the topic, the application needs to wait for a write to
finish before starting a new one (thus, no queue is supposed to be
needed). With the socket NIO2 implementation, you also have to wait for
a write to complete - async or not - before doing a new one on a given
socket, or get a WritePendingException. In websockets, I was "sold" the
NIO2 style, not crazy concurrency scenarios, but there's nothing really
clear in the specification (the WritePendingException is not there).

On the Servlet 3.1 compatibility, right now it doesn't allow mixing
async and non async at all (unlike websockets implied concurrency, this
is in the specification document) so there's going to be a problem with
websockets (which would have to use simulated blocking, and then it
would need the concurrent read/write events to work). So IMO, that's
where the read/write autoblocking capability is helpful, since you don't
have to implement that particular functionality in the user code.

Wouldn't MessageHandler.Whole<InputStream> cause a problem on read ?
Since it would have to block and a simulated blocking done in the user
code couldn't possibly get another "concurrent" read event to continue
reading.

Rémy