The problem is, when you look at ZMQ for the first time, it just looks “meh, sockets”. But that is just the API. ZeroMQ isn’t primarily a networking library! It does a whole lot of stuff, across multiple languages, all through that one single API. So all you have to do to change the scope of your application is change the URL of the socket you plan to connect to…
Sure: With sockets, you can have multiple clients connect to the same destination. In ZMQ you can have multiple clients and servers talk to the same destination without having to know about it inside the application… The multiplexing is transparent and built-in.
And that’s just one aspect of why I really like it.
The work I was going to do over the weekend requires several knock-on changes to the rest of the game-server systems. Players will keep a persistent connection to our map/mission server.
Despite all the subsystems we’ve added, the map mission host has gone from using 80-90% CPU to using single digits with a heavy load. Mostly this is because work has simply gotten moved elsewhere to work around the fact players only talk to it before they spawn and after they despawn.
The map/mission host is supposed to be the server streaming you the latest updates from strat. But, instead, that data has to be forwarded various places. One of these is the cell hosts, which incorporate sending you strat changes with your periodic update, which otherwise describes updates to your vis list and the players on it.
For CP and Facility updates, there is no really good reason for this data to be there – except that you don’t have a connection to the map/mission host. And the system for streaming updates on the map/mission host doesn’t take advantage of modern CPU architecture because it’s only dealing with a handful of users who aren’t spawned.
It occurred to me that we could cut out an awful lot of middle-man and CPU waste by allowing clients to tune in to the stream of updates being sent to the host processes.
DENIED: Right now the strat host uses four different mechanisms for streaming that data to different hosts. Sigh.
Sitting pondering this, I realized that it would take just a few minutes to replace all of them with a ZeroMQ pub/sub socket pair sending out updates, and a second req/rep socket for taking requests for a full snapshot.
Once again, ZeroMQ surprised me by making it trivial.
The throughput is as impressive as always, and it can be fronted by zmq “devices” (little forward applications) so that the strat machine itself doesn’t have to handle the multicasting.
It was also delicious to be able to test interaction with the new interface from pretty much any language I chose: C++, Lua, Python, Perl, Ruby…
So much so that I put together this YouTube video to try and demonstrate some of why I’m really starting to love ZeroMQ.