We have a Server <-> Client connection. The client periodically sends pings
to the server, and Tomcat will respond with a sendPong() on a container
thread, but the same instance of WsRemoteEndpointImplServer we are actively
sending writes on. WsRemoteEndpointImplServer.doWrite() does not seem
thread safe, so I have a feeling that tomcat handling the pongs on a
separate thread is interfering with our constant calls to doWrite() on the
same instance of WsRemoteEndpointImplServer.

If I could synchronize the pong with our application application calls to
sendBinary(), I could fix a potential problem. If it is not supported,
completely understand. I apologize as I have yet to time this perfectly
where the calls do overlap. Do you happen to know if these calls will be
synchronized by the container?

I attached logging into WsRemoteEndpointImplServer (for doWrite() and
onWritePossible()), this includes start and end of the function calls, and
each start will show a hashcode of the WsRemoteEndpointImplServer instance,
and a hashcode of the SendHandler instance (endpointhash:handlerhash),
where two threads are making what seems not so thread safe calls. The first
thread is the application calling down to doWrite() (locked at the
application level) and the second thread is a container thread responding
to a ping:

Thread 1 (Application Synchronized)
--------------------------------------------
http-nio-8443-exec-5: doWrite (start) 909703826:81194941
  java.lang.Thread.getStackTrace(Thread.java:1556)

org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:453)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:341)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:273)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendBytes(WsRemoteEndpointImplBase.java:134)

org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendBinary(WsRemoteEndpointBasic.java:43)

com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.sendBinaryMessage(Jsr356ServerConnection.java:613)

com.thingworx.communications.common.contexts.BaseContext.write(BaseContext.java:95)

com.thingworx.communications.common.messaging.ThingworxMessage.writeContent(ThingworxMessage.java:39)

com.thingworx.communications.server.modules.ServerCommunicationModuleBase.registerServerConnection(ServerCommunicationModuleBase.java:141)

com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.registerConnection(Jsr356ServerConnection.java:332)

com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.onMessage(Jsr356ServerConnection.java:304)
  sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  java.lang.reflect.Method.invoke(Method.java:498)

org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:80)

org.apache.tomcat.websocket.WsFrameBase.sendMessageBinary(WsFrameBase.java:592)

org.apache.tomcat.websocket.WsFrameBase.processDataBinary(WsFrameBase.java:549)
  org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:301)

org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)

org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:71)

org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:185)

org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)

org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)

org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)

org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)

org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)

java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  java.lang.Thread.run(Thread.java:745)
http-nio-8443-exec-5: onWritePossible (start) 909703826:81194941
  java.lang.Thread.getStackTrace(Thread.java:1556)

org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:97)

org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:89)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:453)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:341)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:273)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendBytes(WsRemoteEndpointImplBase.java:134)

org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendBinary(WsRemoteEndpointBasic.java:43)

com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.sendBinaryMessage(Jsr356ServerConnection.java:613)

com.thingworx.communications.common.contexts.BaseContext.write(BaseContext.java:95)

com.thingworx.communications.common.messaging.ThingworxMessage.writeContent(ThingworxMessage.java:39)

com.thingworx.communications.server.modules.ServerCommunicationModuleBase.registerServerConnection(ServerCommunicationModuleBase.java:141)

com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.registerConnection(Jsr356ServerConnection.java:332)

com.thingworx.communications.server.connection.jsr356.Jsr356ServerConnection.onMessage(Jsr356ServerConnection.java:304)
  sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  java.lang.reflect.Method.invoke(Method.java:498)

org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:80)

org.apache.tomcat.websocket.WsFrameBase.sendMessageBinary(WsFrameBase.java:592)

org.apache.tomcat.websocket.WsFrameBase.processDataBinary(WsFrameBase.java:549)
  org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:301)

org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)

org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:71)

org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:185)

org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)

org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)

org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)

org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)

org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)

java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  java.lang.Thread.run(Thread.java:745)
http-nio-8443-exec-5: clearHandler (start) 909703826:81194941
http-nio-8443-exec-5: clearHandler (end)
http-nio-8443-exec-5: onWritePossible (end)
http-nio-8443-exec-5: doWrite (end)

Thread 2 (Tomcat, Unsyncronized?)
--------------------------------------------
http-nio-8443-exec-10: doWrite (start) 909703826:1000491596
  java.lang.Thread.getStackTrace(Thread.java:1556)

org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:453)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:341)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:273)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPong(WsRemoteEndpointImplBase.java:186)

org.apache.tomcat.websocket.WsRemoteEndpointBase.sendPong(WsRemoteEndpointBase.java:62)

org.apache.tomcat.websocket.WsFrameBase.processDataControl(WsFrameBase.java:351)
  org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:290)

org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)

org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:71)

org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:185)

org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)

org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)

org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)

org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)

org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)

java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  java.lang.Thread.run(Thread.java:745)
http-nio-8443-exec-10: onWritePossible (start) 909703826:1000491596
  java.lang.Thread.getStackTrace(Thread.java:1556)

org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:97)

org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:89)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:453)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:341)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:273)

org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPong(WsRemoteEndpointImplBase.java:186)

org.apache.tomcat.websocket.WsRemoteEndpointBase.sendPong(WsRemoteEndpointBase.java:62)

org.apache.tomcat.websocket.WsFrameBase.processDataControl(WsFrameBase.java:351)
  org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:290)

org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)

org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:71)

org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:185)

org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)

org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)

org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)

org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)

org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)

java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  java.lang.Thread.run(Thread.java:745)
http-nio-8443-exec-10: clearHandler (start) 909703826:1000491596
http-nio-8443-exec-10: clearHandler (end)
http-nio-8443-exec-10: onWritePossible (end)
http-nio-8443-exec-10: doWrite (end)


On Fri, Mar 31, 2017 at 9:01 AM, Mark Thomas <ma...@apache.org> wrote:

> On 30/03/17 21:13, Robert Lewis wrote:
> > Is there a way to intercept a ping message to send a pong?
>
> The API doesn't support this.
>
>
> > I need to do this synchronize sends to the endpoint.
>
> Could you clarify your requirement? Tomcat should handle pong messages
> automatically for you (as required by the spec).
>
> Mark
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

Reply via email to