Re: is the Tomcat-7 WsRemoteEndpointImplBase send methods threadsafe, or should we be synchronizing until the Future.get() returns?
On 22/10/2013 00:28, Bob DeRemer wrote: I'm trying to understand how Tomcat's outbound message processing works with respect to making multiple (concurrent) calls against a single RemoteEndpoint.Async using sendText/sendObject. Based on the ExecutionExceptions we got (see below), it seems that we should probably synchronize sends until the Future.get() returns, but I want to check with the community to be sure. I tried searching the javadocs of RemoteEndpoint.Async and associated interfaces, but could not find anything describing the threadsafe nature (existing or not). It appears that the spec lets the implementation determine how to handle stuff under the covers. This is fine, but we just need to understand what that means to multi-threaded code that wants to send messages. There was some discussion [1] in the EG on this point and the conclusion was that the previous message had to complete before the next message was sent. If you batching is used (which Tomcat supports) the semantics for complete change but the previous message still has to complete before the next is sent. I've looked through the specification and I don't see this made clear anywhere. My experience of the J2EE EG's is that in cases like these following the intention of the EG based on the mailing list archive is the way to go. Looking at the Tomcat code, it looks like WsRemoteEndpointImplBase uses a static SendHandler (i.e. TextMessageSendHandler). That is a static definition of a class, not a static instance. A new instance is created for each message. I noticed a little further down in the stack the logic does synchronize around a messagePartQueue, but this seems to be for handling parts of a single message. Correct. That is to ensure correct state management when different threads are sending different parts of the message. Otherwise, it looks like it doesn't expect another message to be sent until it's finished writing out. Correct. It should throw an exception if you try. ExecutionException: In some recent testing of our client/server Endpoint(s) (using a locally built instance of Tomcat 7.0.48), we got ExecutionExceptions when sending messages concurrently without any delay. The errors started with a few Null Ptr(s), then were all wsRemoteEndpoint.inProgress (Message will not be sent because the WebSocket session is currently sending another message) Is my understanding correct, or am I missing something? Thanks in advance for any clarification. HTH, Mark [1] https://java.net/projects/websocket-spec/lists/jsr356-experts/archive/2013-02/message/1 - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
RE: is the Tomcat-7 WsRemoteEndpointImplBase send methods threadsafe, or should we be synchronizing until the Future.get() returns?
-Original Message- From: Niki Dokovski [mailto:nick...@gmail.com] Sent: Tuesday, October 22, 2013 1:11 AM To: Tomcat Users List Subject: Re: is the Tomcat-7 WsRemoteEndpointImplBase send methods threadsafe, or should we be synchronizing until the Future.get() returns? On Tue, Oct 22, 2013 at 3:29 AM, David Bullock david.bull...@machaira.com.au wrote: Hi Bob, I tried searching the javadocs of RemoteEndpoint.Async and associated interfaces, but could not find anything describing the threadsafe nature (existing or not). It appears that the spec lets the implementation determine how to handle stuff under the covers. This is fine, but we just need to understand what that means to multi-threaded code that wants to send messages. JSR 356 Specification Section 5.1 Threading Consideration discusses the topic. In particular; [WSC-5.1-2] - the implementation must not invoke an endpoint instance with more than one thread per peer at a time. [WSC-5.1-4] - a websocket endpoint instance is never called by more than one container thread at a time per peer. cheers Thank you, Niki, for the spec clarification bob I'd have thought that where an interface doesn't declare that it is threadsafe, one cannot assume that it will be. Further, if a RemoteEndpoint represents 'the peer of a web socket conversation', then a RemoteEndpoint, like a conversation, can surely support only a single 'conversation state'? IMHO, the correct choice is for each thread to have its own RemoteEndpoint. If the protocol being used happens to multiplex multiple conversations to/from different endpoints over the same TCP/UDP socket (for example), then the plumbing will do the appropriate synchronization at that point - there would be no advantage (and possibly some big disadvantages) for you to do your own synchronization. Critically, a RemoteEndpoint does not necessarily represent a 'heavyweight' object like a Socket, and you should not be at pains to manage your own pool of them, nor necessarily (unless it made sense for application logic) to have a queue of messages which is dispatched from a single thread. However, I do think that many JSR's which ought to know better are very lame about thread-safety guarantees for application authors, and that more needs to be said in API documentation about patterns for concurrent usage. I encourage you to lobby your particular JSR of use to include this information in future releases of the specification. I did my bit recently at https://java.net/jira/browse/SERVLET_SPEC-81 cheers, David Bullock - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: is the Tomcat-7 WsRemoteEndpointImplBase send methods threadsafe, or should we be synchronizing until the Future.get() returns?
On Tue, Oct 22, 2013 at 3:29 AM, David Bullock david.bull...@machaira.com.au wrote: Hi Bob, I tried searching the javadocs of RemoteEndpoint.Async and associated interfaces, but could not find anything describing the threadsafe nature (existing or not). It appears that the spec lets the implementation determine how to handle stuff under the covers. This is fine, but we just need to understand what that means to multi-threaded code that wants to send messages. JSR 356 Specification Section 5.1 Threading Consideration discusses the topic. In particular; [WSC-5.1-2] - the implementation must not invoke an endpoint instance with more than one thread per peer at a time. [WSC-5.1-4] - a websocket endpoint instance is never called by more than one container thread at a time per peer. cheers I'd have thought that where an interface doesn't declare that it is threadsafe, one cannot assume that it will be. Further, if a RemoteEndpoint represents 'the peer of a web socket conversation', then a RemoteEndpoint, like a conversation, can surely support only a single 'conversation state'? IMHO, the correct choice is for each thread to have its own RemoteEndpoint. If the protocol being used happens to multiplex multiple conversations to/from different endpoints over the same TCP/UDP socket (for example), then the plumbing will do the appropriate synchronization at that point - there would be no advantage (and possibly some big disadvantages) for you to do your own synchronization. Critically, a RemoteEndpoint does not necessarily represent a 'heavyweight' object like a Socket, and you should not be at pains to manage your own pool of them, nor necessarily (unless it made sense for application logic) to have a queue of messages which is dispatched from a single thread. However, I do think that many JSR's which ought to know better are very lame about thread-safety guarantees for application authors, and that more needs to be said in API documentation about patterns for concurrent usage. I encourage you to lobby your particular JSR of use to include this information in future releases of the specification. I did my bit recently at https://java.net/jira/browse/SERVLET_SPEC-81 cheers, David Bullock - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org