jsr356-experts@websocket-spec.java.net

[jsr356-experts] MessageHandler collection state changes and threading

From: Joakim Erdfelt <joakim_at_intalio.com>
Date: Wed, 3 Apr 2013 11:05:19 -0700

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?

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