20150616

Sleep deprivation and server architecture

If I sleep about 4 hours for a few days, I become more concentrated (can get work done more easily), more creative (less energy for my mind to filter out ideas bubbling up from the unconscious), and less able to create mental constructions (so I won't come up with an elegant architecture). If I sleep less then 6 hours, and then I work 8 and a half hours, then I will be absolutely useless.

I also learned that my circadian rythm does everything it can to stop me from getting up in the morning and going to bed in the evening. When I'm working in night shift, I usually get up around noon, and go to bed around 4 AM. (Also, if I'm left to myself, I will usually sleep ~10 hours.) The best thing is that at night everything is quiet, so I can think. But when I have to work from 6 am to 14:30 pm, this tendency to not sleep enough takes its toll on my ability to work on my game. This is why I didn't do much in the past week.

Before that, a first draft of the game server was finished. The first problem I ran into was this: when a client connects, it sends its name and intended color to the server, then asks for the player list. If this was done in a quick succession, then it received a list of players without its own data updated. Why?

Let's take a look at how the server architecture looked like:



In a nutshell: clients connect to the server. The Listener thread listens to them, and spawns threads for each client (not depicted on the picture, think them as part of the Listener box). Those threads send and receive messages to and from MessageRouter, which forwards the messages to either CommandInterpreter (if it is a server-administrating command, starting with the "recon" prefix), or LogicDaemon (if it is a message to the game server itself). Then they both send requests to the ServerManager, containing modifications to the actual server data.

The problem is that I'm using Software Transactional Memory (STM), so any transactions I make to an object cannot be seen from outside until it is finished. It means that while these requests are not finished, one can still access the old state of said object. This is why the client got the message that - in spite of the client has told its name - it doesn't have name assigned to it. If it were to ask for the player data, say, half a second later, it would have correctly seen its name in the player list.

What I did was to merge four of the threads into one: MessageRouter, LogicDaemon, CommandInterpreter and ServerManager.



Results: now if the client sends the message too fast, the server doesn't even get it. Fail. But everything else works as it should, so I hope it's just a minor something that I have overlooked. (EDIT: Figured out the reason, it indeed was a problem with how the server parsed the incoming messages. Was a fault of my own laziness.)

This is a thesis on writing a game server in Erlang. it seems, most of the components of the server can be found in my server architecture as well (with some differencies). I guess I can be moderately proud of myself.

No comments:

Post a Comment