Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] Why does WebsocketClient work on multi threads as default?

Sorry for being late to reply. I understand that your comment was about
receiving messages. My questions is too.

My concern is like as follows. If a @OnWebSocketMessage callback execute
some very long processing like the following snippet, a context switch
might happen in a method doVeryLongProcessing because WebSocketClient
runs with multithread. In that case, even if onMessage receives a
message A then B, B might be processed earlier than A.

  @OnWebSocketMessage
  public void onMessage(final byte buf[], final int offset,
                        final int length) {
     doVeryLongProcessing();
 }

 void doVeryLongProcessing() {
     // a context switch might happen here

     // .....
 }

This is unwanted situation for my project. So, I specify a fixed thread
pool to a WebSocketClient constructor so that WebSocketClient runs on
only one worker thread and grantee the message order in the
@OnWebSocketMessage callback.

  // one for internal scheduling thread, another one for worker thread
  Executor executor = Executors.newFixedThreadPool(2)
  WebSocketClient client = new WebSocketClient(executor);

So, let me get back to my original question. I think a context switch in
@OnWebSocketMessage callback is unwanted situation in many cases. So, I
am curious why WebSocketClient runs with multithread as default.

Yohei Onishi
OGIS-RI Co.,Ltd.

On 2015/12/03 0:56, Joakim Erdfelt wrote:
> My commentary was all about receiving messages, not sending them.
> Sending them is always in order, regardless of technique, as the 
> protocol dictates that.
> (Its not possible to overlap messages in WebSocket)
> 
> Joakim Erdfelt / joakim@xxxxxxxxxxx <mailto:joakim@xxxxxxxxxxx>
> 
> On Wed, Dec 2, 2015 at 8:40 AM, Yohei Onishi <vivre214@xxxxxxxxx 
> <mailto:vivre214@xxxxxxxxx>> wrote:
> 
>     Hi Joakim,
> 
>     Thank you for your detailed explanation. I understand that the
>     message order is guaranteed within the Websocket client library.
>     But my concern is that the message order is not guaranteed in a
>     message callback of client code.
>     For example, if a context switch happens during the process of
>     onMessage(Stream(A)), onMessage(Stream(B)) might be
>     completed earlier than Stream(A);
>     # I assume that the following "onMessage" is in the same class.
> 
>     > Your code:
>     >   [onMessage(Stream(A))], r1, r2, r3, r4, r5, [A.close()]
>     >                                [onMessage(Stream(B)], r1, r2, r3, [B.close()]
> 
>     I suppose that the only way to guarantee the message order in client
>     code is to limit a number of thread for WebsocketClient.
> 
> 
>     Yohei Onishi
> 
>     On Wed, Dec 2, 2015 at 12:38 AM, Joakim Erdfelt <joakim@xxxxxxxxxxx
>     <mailto:joakim@xxxxxxxxxxx>> wrote:
> 
>         Within a single connection, the message order (more precisely
>         the START of the message) is guaranteed.
>         The only situation where this nuance is important to understand
>         is when you are using Streaming message handling.
> 
>         Each incoming message results in a new stream, that must be
>         handled via dispatching the start of the message to your handler.
>         If your handling isn't fast enough, then it might seem that you
>         are getting messages out of order, but in reality you are not.
>         Its just that you got the following ...
> 
> 
>         On the wire:
>             [A], 1, 2, 3, 4, 5, [A-FIN], [B], 1, 2, 3, [B-FIN]
> 
>         Dispatching:
>             [A]                          [B]
> 
>         Your code:
>             [onMessage(Stream(A))], r1, r2, r3, r4, r5, [A.close()]
>                                          [onMessage(Stream(B)], r1, r2,
>         r3, [B.close()]
> 
> 
>         Which make it appear as if you got B before A finished, which is
>         very likely and probable.
>         There was a time period where we would not dispatch Stream(B)
>         until Stream(A) was closed, but this behavior was highly
>         confusing to users of the API.
>         And to accomplish it we would have to stop reading from the
>         WebSocket endpoint (even CLOSE/PING/PONG frames!) until that
>         occurred.
>         Either that or we start queuing messages, especially problematic
>         if the messages are short!
> 
>         With short messages, its very probable that a single network
>         read can result in more than 1 websocket message.
>         In this case, there would be multiple dispatches, in quick
>         succession.
> 
> 
>         Joakim Erdfelt / joakim@xxxxxxxxxxx <mailto:joakim@xxxxxxxxxxx>
> 
>         On Tue, Dec 1, 2015 at 7:47 AM, Yohei Onishi <vivre214@xxxxxxxxx
>         <mailto:vivre214@xxxxxxxxx>> wrote:
> 
>             Hello,
> 
>             If WebsockectClient class is initialized without a
>             parameter, it launches about 8 threads (1 for internal
>             scheduling, 7 threads for working). Why is it designed to
>             work on multi threads as default? What is typical use case
>             for multi threads?
> 
>             In my projects, we found that we could not guarantee message
>             order with default setting (multithread) because of a
>             context switch. For example, even if WebsocketClient receive
>             message A then B, message B  might be processed first in a
>             @OnWebsocketMessage callback if a context switch happens.
> 
>             We care message order in my project, so we usually specify
>             an executor like below.
> 
>             WebsocketClient client = new
>             WebsocketClient(Executors.newFixedThreadPool(2));
> 
>             (Note) We need at least two threads, one for internal
>             scheduling and the another for actual working thread.
> 
>             Thanks,
>             Yohei Onishi
> 
>             _______________________________________________
>             jetty-users mailing list
>             jetty-users@xxxxxxxxxxx <mailto:jetty-users@xxxxxxxxxxx>
>             To change your delivery options, retrieve your password, or
>             unsubscribe from this list, visit
>             https://dev.eclipse.org/mailman/listinfo/jetty-users
> 
> 
> 
>         _______________________________________________
>         jetty-users mailing list
>         jetty-users@xxxxxxxxxxx <mailto:jetty-users@xxxxxxxxxxx>
>         To change your delivery options, retrieve your password, or
>         unsubscribe from this list, visit
>         https://dev.eclipse.org/mailman/listinfo/jetty-users
> 
> 
> 
>     _______________________________________________
>     jetty-users mailing list
>     jetty-users@xxxxxxxxxxx <mailto:jetty-users@xxxxxxxxxxx>
>     To change your delivery options, retrieve your password, or
>     unsubscribe from this list, visit
>     https://dev.eclipse.org/mailman/listinfo/jetty-users
> 
> 
> 
> 
> _______________________________________________
> jetty-users mailing list
> jetty-users@xxxxxxxxxxx
> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
> https://dev.eclipse.org/mailman/listinfo/jetty-users
> 



Back to the top