jsr356-experts@websocket-spec.java.net

[jsr356-experts] Re: MessageHandler collection state changes and threading

From: Joakim Erdfelt <joakim_at_intalio.com>
Date: Thu, 18 Apr 2013 15:00:41 -0700

I went ahead and opened a jira for a clarification of this topic.

http://java.net/jira/browse/WEBSOCKET_SPEC-190

--
Joakim Erdfelt <joakim_at_intalio.com>
webtide.com <http://www.webtide.com/>
Developer advice, services and support
from the Jetty & CometD experts
eclipse.org/jetty - cometd.org
On Tue, Apr 9, 2013 at 7:04 PM, Mark Thomas <mark_at_homeinbox.net> wrote:
> On 03/04/2013 14:05, Joakim Erdfelt wrote:
>
>> Question on expectations of MessageHandler collection changes.
>>
>> Let me start by showing a scenario:
>>
>>  1. Endpoint is opened
>>  2. Socket itself registers Session.addMessageHandler(new
>>
>>     ChatMessageHandler()); // implements MessageHandler.Whole<String>
>>  3. Incoming websocket frame. (op=TEXT, fin=false)
>>  4. Implementation starts queuing up for whole message.
>>  5. Incoming websocket frame. (op=CONTINUATION, fin=false)
>>  6. Implementation appends frame for whole message.
>>  7. Socket does Session.removeMessageHandler(**chatMessageHandler);
>>  8. Socket does Session.addMessageHandler(new EventMessageHandler()); //
>>     implements MessageHandler.Whole<String>
>>  9. Incoming websocket frame. (op=CONTINUATION, fin=true)
>> 10. Implementation appends frame for whole message.
>> 11. Implementation notifies EventMessageHandler.onMessage(**message);  //
>>
>>     Is this right?
>>
>> The implementation would need to make a judgement call at #4 to say that
>> the incoming TEXT frame is for a MessageHandler.Whole<String> and start
>> queueing up the message. (otherwise for MessageHandler.Partial, it can
>> start notifying the MessageHandler immediately)
>> However, when the implementation reaches step #11, the
>> MessageHandler.Whole<String> has been swapped out.
>>
>> Question is, should the implementation lock the TEXT MessageHandler at
>> step #3 (initial frame of message) till it is called at step #11 (last
>> frame of message)?
>> The PFD1 Javadoc for step #8 (Session.removeMessageHandler(**)) says that
>> the remove should block until the handler is done processing and its no
>> longer in use.
>>
>> In short, I'm just trying to put some rules around the
>> Session.addMessageHandler and Session.removeMessageHandler, along with
>> making the usage of provided MessageHandlers consistent in a threading
>> scenario.
>>
>> One technique, would be to prevent altering the MessageHandler
>> collection while in the middle of a websocket message.  Only allowing
>> changes between websocket messages.
>> But this seems like a recipe for a bad time with threading / dispatching
>> / locks / etc ...
>>
>> The technique Jetty has settled on, but we don't know if this is sane,
>> is to pull from the MessageHandler collection at step #3 & 4 (initial
>> incoming frame for the start of websocket message) and continue to use
>> it for the rest of the message, making the MessageHandler collection
>> itself not need any extra concurrency rules and eliminating the need to
>> lock on step #7 and #8.
>>
>> I am also working with a scenario where the Session starts with a
>> MessageHandler.Partial and then gets swapped out for a
>> MessageHandler.Whole.  This means that I'll be treating a
>> MessageHandler.Partial with the same rules for and entire websocket
>> message.  Once you start a websocket message, you continue to use the
>> same MessageHandler for the entire message.
>>
>> In our approach, the blocking requirement of
>> Session.removeMessageHandler() is irrelevant.  In our approach removing
>> the MessageHandler is just an indication that future messages should not
>> use this MessageHandler.
>>
>> Is this a sane approach?
>>
>
> I'm all for clarifying these sorts of edge cases sooner rather than later.
> Your suggested approach seems reasonable to me.
>
> It does mean we would need to change the Javadoc for
> Session.removeMessageHandler()
>
> Mark
>
>