[ https://issues.apache.org/activemq/browse/AMQ-988?page=all ]
Rob Lugt reassigned AMQ-988: ---------------------------- Assignee: james strachan > Thread synchronization error in TcpTransport > -------------------------------------------- > > Key: AMQ-988 > URL: https://issues.apache.org/activemq/browse/AMQ-988 > Project: ActiveMQ > Issue Type: Bug > Components: NMS (C# client) > Affects Versions: 4.0.2 > Environment: Windows > Reporter: Rob Lugt > Assigned To: james strachan > > I have a problem where my C# client application crashes when placed under > load. It's taken a while to get to the bottom of it, but I believe I have > identified the problem and luckily there's a simple solution. > The AMQ .Net client uses a common pattern where a full-duplex TCP/IP > connection is established with the broker, and the client uses two threads to > concurrently read and write data to/from the underlying socket - one thread > reading from a Reader object and the other writing to a Writer object. > The TcpTransport.Start() method contains the following:- > NetworkStream networkStream = new NetworkStream(socket); > socketWriter = new OpenWireBinaryWriter(networkStream); > socketReader = new OpenWireBinaryReader(networkStream); > This pattern is explicitly allowed in Java and Win32 applications, but .Net > is a little vague on the subject. The Microsoft documentation [1] suggests > use of the asynchronous read/write calls for multithreaded applications, but > that would significantly complicate the C# client which relies on blocking > stream behaviour. On the same doc page > Microsoft does specifiy that the Socket class is thread-safe, which I take to > mean that concurrent read/write calls are permitted, however the same is not > true of NetworkStream [2]. > Perhaps it would be reasonable to expect NetworkStream to have no internal > state other than the Socket it contains, but apparently this is not the case > because I've identified that it is a corrupt NetworkStream which is causing > my application to crash under load. After some experimentation and a fair > amount of load testing, I think the solution is a simple change to the > TcpTransport.start() method to use a separate NetworkStream for input and > output operations. e.g. :- > NetworkStream inputNetworkStream = new NetworkStream(socket); > NetworkStream outputNetworkStream = new NetworkStream(socket); > socketWriter = new OpenWireBinaryWriter(inputNetworkStream); > socketReader = new OpenWireBinaryReader(outputNetworkStream); > This works for me and my test client has now been running for 16 hours > without crashing (before it would rarely last longer than 10 minutes). > Regards > Rob Lugt > [1] http://msdn2.microsoft.com/en-us/library/system.net.sockets.socket.aspx > [2] > http://msdn2.microsoft.com/en-us/library/system.net.sockets.networkstream.aspx -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/activemq/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira