jsr340-experts@servlet-spec.java.net

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

From: Mark Thomas <markt_at_apache.org>
Date: Tue, 30 Apr 2013 11:21:38 +0100

On 29/04/2013 10:51, Rémy Maucherat wrote:
> 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).

WebSocket does require the previous message to have been sent before the
next message is sent (unless in batch mode but the way that is defined
doesn't really change things).

The spec and Javadoc isn't as clear as it could be but sending a message
before the previous message has finished will trigger an ISE.

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

My question with auto blocking is how does the Servlet container know if
a read or write is meant to be blocking or not? The user code (the
WebSocket implementation) knows but there is no API that enables it to
tell the container. I had originally thought that flush() could be used
to do this (i.e. block if flush() is called) but as you pointed out,
that might work in an HTTP upgrade scenario but not in a Servlet one.

Using flush(0 in this way would work for WebSocket since it used HTTp
upgrade but having the same method behave differently for HTYTP Upgrade
and async servlets doesn't seem right either.

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

The container is required to buffer the message until it is fully
received so there is no blocking when user code does the read.

So far, I haven't found any blockers to using allowing one read thread
and one write thread.

Mark