I was again up against an interesting problem recently which was solved by going complex and then doing a full turn-around and resorting to a much simpler approach which worked well. I'm currently developing a component at work whereby it needs to interact with another component. Each of the components are separate processes and so the communication I've implemented using named pipes. The solution is in place but I came accross an interesting problem.

I've implemented the basics in a simple loop which is in a new thread that basically waits for the other component to connect to us, once it does that it processes the communication(while blocking any other connects - its synchonous and this is fine for our purposes). Once the connection is accepted and then its processed, we again wait for new connections. At this point the other component can send another message. If it had tried to while we were processing the last message, it would just wait. Anyway because the named pipes server is actually within a Windows Service, I found that this mechanism keeps the service from stopping correctly when you issue a restart/stop command from Windows. The result was that the exe that underlies the service stays running. If you start the service(while the other exe is still running) things catch on fire and people die. So. The problem was that the two processes would basically trample over each other's feet as both would be providing the named pipe connection service. I couldn't understand why this was happening - why the exe kept running. Then it hit, me. Its because the thread is stil sitting there listening for the next connection and the exe will not stop because a child thread it still running! 

Initially thats great that i found a reason for it, but I then had no way to shutdown the listening thread. I was thinking that I'd need to implement the named pipes server as a asynchrnous routine as this would make it interruptable and then we can stop it listening when we get a stop command from windows. Doing that meant that I'd have to re-architect the named pipe listening thread. It was new, the code would need to be re-tested and it sucked big time for me. Then I tried to instead kill the thread by aborting it unceriomonsiously. Never a good idea but netter than re-writting everything just so can restart the service! That also started back firing as that didn't work. I went home that day pretty frustrated. i knew that I'd probably have to reimplment the functionality...

As it happens, i was in the shower as usually when i got a good idea which solves the problem and does't change the already implemented(and working/suitable) solution: Send myself a message on restart/stop that will shutdown the listening thread. Clearly the thread is waiting for a connection and preventing our thread from shutting down. So send it a message which its waiting for and let that message mean that the server doesn't have to wait anymore, so instead of it processing the message and re-listeninig - it just says 'oh this is a stop listening message'. lets break the loop now. Brilliant! That works well. The service shuts down or restarts, the thread closes itself down upon getting the 'shutdown' message (which we send to ourself) and bobs yer uncle.

So again, looking for a simple solution came from going into the depths of complexity to realize it. And as a result, it was easy to now move onto the next problem which was to send responses/acknowledgments back to the component that sends a message. Usually we'd just 'fire and forget' without the sender getting anything back after sending a message to the named pipe server. I just assumed that everything went according to plan. That was fine in the initial sprints but as the solution got more mature and the requirements started stacking up, it became essential that a acknowledgment came back with the message. So now the client waits for a reply after each message sent, and the server always responds with at least a ackolwdgement that things completed. In the case that they dont complete, the reply is an error reply and the client and determine what to do next. But I'd never had been able to start(mentally for my own sanity) this functionality had I not solved the problem with with the service restart problem. i could have but it would have been in the back of my mind all the time while doing this code. 

A victory for simplicity over complexity.