I will attempt to create a test case, but is is common with concurrency
issues it isn't easy.
The out of order delivery on Jetty is fairly low probability though easy to
understand from reading the implementation. In their case a stream decoder
is started on a separate thread and then 'pushed' data as it arrives on
some other thread. A subsequent message does the same, but invariably the
task will be run on yet another thread. When decoding is complete for a
message, the @OnMessage method is invoked on the end point using the thread
that ran the decoder. With very short messages arriving in a continuous
stream, sometimes a decoder thread will be suspended, before it has
delivered its result, sufficiently that the decoder thread for the
subsequent message completes first.
I suppose this behaviour could be forced by inserting a small random sleep
in the decoder just before it returns the result. That would be equivalent
to the effect of the thread losing its time slice, but much higher in
probability.
Mark Thornton
On Monday, 10 March 2014, Pavel Bucek <pavel.bucek_at_oracle.com> wrote:
> Hi Mark,
>
> if you have simple testcase based on JSR 356 API, the best would be just
> try and if you encounter something which does seem like violation of the
> specification or.. it just does not seem correct, feel free to share that
> sample with us and we can take a look.
>
> Generally speaking, messages should be received in order, but we might not
> have the test which fits your usecase.
>
> Concurrent invocation of decoders would fall into same category as
> previous - I don't believe Tyrus does that, at least in case when
> everything is in "per session" scope (default).
>
> Let me try to play with this little bit and if you can, please run your
> sample in top of Tyrus and let us know the results. Or you can just share
> JSR 356 part of it and we can recreate the (test)case from it.
>
> Thanks,
> Pavel
>
> On 08/03/14 09:59, Mark Thornton wrote:
>
>> I am using a number of web socket providers (tyrus, jetty and tomcat) and
>> am looking at what behaviour is actually guaranteed.
>>
>> I had expected that messages (@onMessage) would be delivered in order,
>> but have discovered that in Jetty at least this isn't true when a stream
>> decoder (Decoder.TextStream or Decoder.BinaryStream) is used. Note that
>> this is with an instance per peer (and in fact my tests only have one peer).
>>
>> Another (related) surprise was that such stream decoders may be invoked
>> concurrently. The standard seems to guarantee that doesn't apply for
>> Encoder's (though again I'm not sure that is true in Jetty).
>>
>> So, my question is would Tyrus users have been surprised by such
>> behaviour?
>>
>> Mark Thornton
>>
>>
>