+1 to Scott's suggestion. It's a clean, simple, understandable
specification and implementation. While Danny's offers a certain bit of
power and flexibility, I'd rather start with something more readily
understood and expand based on usage patterns rather than try to guess
about what people will need too much. I can't imagine too many cases where
someone will need multiple encoders/decoders but those people are free to
implement an aggregating encoder/decoder and compose their needs into "one."
On Sat, Nov 3, 2012 at 7:35 AM, Mark Thomas <mark_at_homeinbox.net> wrote:
> On 03/11/2012 00:36, Scott Ferguson wrote:
> > On 11/2/12 4:59 PM, Danny Coward wrote:
> >> Hi folks,
> >>
> >> Another question that has come up as people look at the API and
> >> implement it is the issue of precedence when an endpoint has multiple
> >> MessageHandlers. I wrote up a little proposal that seeks to define how
> >> the container is supposed to select which of potentially numerous of
> >> MessageHandlers to callwhen a web socket message arrives.
> >
> > I've been working through this in our implementation. (Decoders is a
> > different/related/bigger issue.)
> >
> > More comments inline, but the summary is I think it's best to only allow
> > one Text handler and one Binary handler, and throw an
> > IllegalStateException at registration time if more than one of each type
> > is registered.
> >
> >>
> >> Principles
> >>
> >> Each web socket message is handled by at most one message handler
> >
> > Yes.
> >
> >> Messages that are unhandled result in calls to onError/_at_WebSocketError
> >> callbacks, so developers can always know if a message does not get
> handled
> >
> > Yes.
> >
> >> Developer provided decoders are chosen before platform decoders.
> >
> > Our decoder logic is messed up for bigger reasons, but I want to put
> > that discussion off to a different thread.
> >
> >> If a decoder fails, the error is delivered and no more decoders are
> >> attempted.
> >
> > Ditto. (decoders messed up).
> >> MessageHandlers for custom objects (provided a Decoder exists) are
> >> chosen over the basic MessageHandlers
> >
> > Ditto. (decoders messed up).
> >>
> >> Process
> >
> > Comment at end.
> >>
> >> 1. a whole string message arrives
> >>
> >> a) if there is an MessageHandler.AsyncText handler - call it once with
> >> the whole string and stop, otherwise continue...
> >> b) if there is an MessageHandler.CharStream handler - call it once
> >> using the whole string as the source and stop, otherwise continue...
> >> c) if there is a MessageHandler.DecodedObject<T> where T is not
> >> String, then try to find a Decoder.Text<T> or a Decoder.TextStream<T>.
> >> Look, in order, through developer provided ones (single list, may
> >> contain both Text and TextStream types). Then look through platform
> >> provided ones. Use the first match to decode it. If the decode
> >> completes without error, call the MessageHandler and stop, if not,
> >> call the onError/_at_WebSocket method with the decode exception and stop.
> >> If there is no suitable Decoder, continue....
> >> d) if there is a MessageHandler.Text handler handler, call it, using
> >> the first developer provided Decoder.TextStream<String> or
> >> Decoder.Text<String>, if any.
> >> e) If the message is still unhandled, call back on the
> >> onError/_at_WebSocketError method. We may need a new exception type for
> >> Unhandledmessages.
> >>
> >> 2) a whole binary message arrives: use analogous process to 1)
> >>
> >> 3) the first piece of a chunked string message arrives.
> >>
> >> a) if there is an MessageHandler.AsyncText handler - call it
> >> repeatedly until all the message has arrived and stop, otherwise
> >> continue..
> >> b) if there is an MessageHandler.CharStream handler - call it with a
> >> Reader linked to the incoming parts, and stop, otherwise continue..
> >> c) if there are MessageHandler.Text or MessageHandler.DecodedObject
> >> handlers, wait for all the string pieces to arrive, building the whole
> >> message as you go (subject to the buffer limit defined on the
> >> *Container). If the buffer limit is exceeded call the
> >> onError/_at_WebSocketError method on the endpoint. Otherwise, using the
> >> whole message, jump to the analogous steps for 1c), d) and e) to
> >> process the complete message.
> >>
> >> 4) the first piece of a chunked binary message arrives: use analogous
> >> process to 3)
> >
> > Imagine the replacement specification:
> >
> > 1) If a text message comes in (chunked or not), the single text
> > MessageHandler is used.
> >
> > 2) If a binary message comes in (chunked or not), the single binary
> > MessageHandler is used.
> >
> > Done.
> >
> > I don't think there's any practical power lost by this restriction, and
> > the limitation is far outweighed by the benefit of a simpler definition.
>
> I must confess that my own implementation work got stuck in the weeds of
> working with HTTP upgrade before I got distracted by other work and I
> haven't made much progress; certainly not enough to comment on this
> based on implementation experience. That said...
>
> My instinct as I read Danny's proposal was that it was looking awfully
> complicated and that a cleaner solution would be desirable if such a
> thing was possible. Scott's proposal looks like that cleaner solution
> and gets my +1 with the caveat that I haven't looked at implementing it.
>
> Mark
>
>
--
You can find me on the net at:
http://antwerkz.com http://antwerkz.com/+
http://antwerkz.com/twitter http://antwerkz.com/github