LoCo Day 25

Now the server actually runs the game when everyone in a room is ready to play, instead of just waiting for a few seconds and then claiming the game is over.

At the moment, however, there’s nothing on the client side that understands the game, so the next chunk of code to write is the JavaScript (ugh) that implements the game logic on the browser side. When the game is actually running, the client and server are running the game logic relatively independently of one another, with messages being send back and forth only to update each other when a player changes direction. This way, there won’t be a bunch of unnecessary traffic crossing the network.

I also think at some point I’m going to need to change how the server maintains the state of all the rooms. Right now, it’s a Map stored inside an MVar, but that means the MVar effectively acts as a global exclusive lock for anything that wants to do anything with a room. Not a problem for testing, but I bet that’ll be a big problem with even just a moderate load. I think I’ll replace that with a TVar for the Map itself, and another TVar for each room. Using software transactional memory instead of exclusive locks will allow multiple threads (i.e., multiple requests) to operate on pieces of the state at the same time. This matches the actual use much more nicely:

  • Most operations are just sending and receiving messages via a room’s channel, so the room and Map themselves aren’t being modified. Read-only operations are nice for STM.
  • Less commonly, an existing room is being modified (e.g. someone entering or leaving, or games being started up). This modifies an individual room but leaves everything else alone, and with each room having its own TVar, these within-room writes can be isolated from other write operations.
  • More rarely, rooms are created or destroyed, which is the only time when the structure of the overall Map itself needs to change.

Using TVars instead of an MVar also gives a bit more consistency with the message-passing bits of code, which are already using STM objects (namely TChans and TVars). Perhaps each request could be treated as a single STM transaction, instead of separate bits and pieces being run separately and intermixed with other IO operations. But since the next chunk of functionality will almost be all client-side, I probably won’t get around to migrating more stuff to STM for a little while.

Comments are closed.