jsr340-experts@servlet-spec.java.net

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

From: Rémy Maucherat <rmaucher_at_redhat.com>
Date: Thu, 23 May 2013 10:50:34 +0200

On 05/23/2013 12:57 AM, Greg Wilkins wrote:
>
>
>
> On 22 May 2013 19:20, Mark Thomas <markt_at_apache.org
> <mailto:markt_at_apache.org>> wrote:
>
> The current sticking point is the non-blocking writes that return a
> Future. Consider the following sequence:
>
> - Container receives WebSocket message
> - Container thread triggers onMessage processing in app
> - app (still on container thread) sends a message in response
> using the
> Future style
> - app calls Future.get()
>
>
>
> I think that the issue here is that you should not call application
> level callback from an async IO callback.
>
> async IO callbacks should not block and calling arbitrary application
> code is possibly going to block with things like databases,
> webservices, let alone request/response IO.
>
>
>
> Other options I have considered:
> 1 Change the non-blocking aspects of the API in Servlet 3.1 to use the
> same style as WebSocket.
>
> 2 Expose the object being used for the one thread per request lock
> through the Servlet API so the WebSocket API can use it rather than
> its own lock to implement blocking. This could enable the
> Servlet API
> to detect when a container thread was blocked and therefore allow
> another thread to do some work on the same request.
>
> 3 Give up and use some the container internals directly.
>
>
>
> Option 4 - to call any code that might block (eg the onMessage
> callback), use AsyncContext.start(Runnable) to obtain a thread to do
> the call into the application.
>
> This allows us to keep 1 container dispatched thread limit, but that
> layers like a JSR356 implementation can request another container
> thread to do independent calls into application code.
>
I mentioned that in an earlier message, but I don't think AsyncContext
is available in upgraded mode ...

Quote of the message:
"Without the clarification, I would say the websocket library has to be
able to access the container thread pool at some point to tell it to run
its code (to cover the fact that onMessage can do blocking operations).
The AsyncContext.start(Runnable) functionality could have been used
there, but I don't think it is available."

And:
"So the possible solutions (in my personal order of preference) are:
- Adding autoblocking (it is vaguely mentioned as being "illegal" right
now; if this is not mentioned anymore, the API semantics apply, and they
should block): it is easy, sneaky and solves the problem, but the
implementation changes are also significant
- Allowing (actually: requiring) concurrent read/write events: it sounds
simple but it leads to more issues, and it should really only be done
once upgraded, but it could still lead to implementation problems (needs
investigation)
- Add a WebConnection.start(Runnable): it makes the API clunky and
people would wonder why it is there"

Note: I made a mistake then, since [my take on] autoblocking doesn't
solve all the websockets use cases.

Actually, it could be nice to have both items (concurrent read/write in
upgrade mode + WebConnection.start(Runnable) to allow tapping into the
container pool).

Rémy