We're hiring!

We're actively seeking developers for our new Detroit location. Learn more

Putting a Stop to WebSockets and Winstone

Push The ButtonRecently I’ve been working on a project combining an HTTP server and a WebSockets server. Traffic from both HTTP and WebSocket clients can affect server state and consequently an HTTP client can affect a WebSockets client and vice-versa. We are prototyping this in JRuby as a single .war file using warble. The HTTP server is using Winstone, and the WebSockets server is using em-websocket. Since we are also prototyping clients of both stripes, and testing overall behavior with Cucumber, it is crucial that the server stops and restarts quickly as we test. However, getting a simple “stop” message through was a bit like going through an obstacle course.

Generally speaking, when running Winstone from the command line, it expects a straightforward Ctrl-C (or SIG-INT) to bring it to a close.  In fact it traps this signal and begins its shutdown routine.  In our case, though, the WebSockets server we launched alongside our Sinatra web application decided it needed to do the same thing.  So the Websockets code trapped the SIG-INT, shut down eventmachine, and just assumed that everything would sort itself out.  Not so.

That was fairly simple to fix.  We just stopped trapping the SIG-INT, and then Winstone shut down properly from the command line.  At that point we thought we were in the clear.  Again we were mistaken.  Later on we realized that any unexpected Exception in our Websockets code would stop the Websockets server or corrupt its state, but let Winstone keep going with the HTTP sever.  For our tests, we would prefer any unexpected Exception to trigger a fail of the scenario in Cucumber and shut down the entire server.  So we tried raising the error to Winstone rather than swallowing it at the WebSockets level, but it ignored the error.  We also tried raising an Interrupt exception – no dice.  It looked like Winstone really didn’t want to be stopped from the inside.  In frustration, and wanting to get on with our tests, we decided to go for the less graceful approach – java.lang.System.shutdown.  Ugly, but very effective.

A few days later, with the bitter taste of an abrupt and messy solution still lingering, I decided to dig into the Winstone documentation and see if there was a more graceful way to shut down Winstone from inside our app code.  I didn’t find one, but I did find a perfectly workable solution to use from the “outside”: the controlPort.  All I had to do was open up a TCP connection to localhost in our code when an error happened, send down one bit, and – voila!  It just goes to show that every now and then it pays to go look at the documentation before you go traipsing through the code.  Now we have a server that restarts gracefully on error, and em-websocket and Winstone don’t get in the way.

This entry was posted in Languages, Prototyping, Testing, Tools, Web and tagged , , . Bookmark the permalink. Both comments and trackbacks are currently closed.

2 Comments

  1. Gregory Ostermayr
    Posted July 27, 2012 at 10:45 am

    Could you give some information on how exactly you managed to place eventmachine in a war file? I was under the impression in a war type of setup other servers and background processes would have to live outside the war file. Any information you could point me to would be helpful.

    • William Ryan
      Posted August 8, 2012 at 9:11 am

      Hi. Sorry to take a while to get back to you. It’s been a while since I worked on that project, but basically our JRuby code just opens up a new thread for the websocket server, in which we start eventmachine. Then the main thread launches the HTTP server. We had to use EM.next_tick on several occasions while handling HTTP requests, to make sure our business logic ran in the same thread as eventmachine. Beyond that, however, the two servers can exist as separate threads within the same Java instance without too many difficulties. Hope that helps.