Server Snapshot

Started by
3 comments, last by SkandarKamel 12 years, 5 months ago
Hi everyone,

I'm writing a Chess matchmaking system with a lobby, rooms, general chat and the usual stuff. The server is a producer-consumer design : A reader thread polls the sockets for new data and places it on some bloquing queue depending on the event type, and a pool of worker threads poll the queues to broadcast the event. What I'm uncertain about is how to handle a new comer. When a new user enters he needs to receive the state of the world. This state is constantly changing and I'm not sure how to synchronize well. The naive solution would be to stop the reader thread, drain the queues, create a snapshot of the server and send it to the new comer, then resume everything. Does anyone have some suggestion for this problem?
Advertisement

When a new user enters he needs to receive the state of the world. This state is constantly changing and I'm not sure how to synchronize well.


Do you need for the world to be 100% "correctly" synchronized? If so, you need a blocking operation that allows you to enqueue the entire consistent world state, and insert the newcomer in the world state update queue, without the world state being mutated. If people join/leave a lot, this may become a bottleneck.

Else, you can build a system that synchronizes up to X objects per second. Keep a queue of objects that need to be synchronized per client. When a client joins, add a reference to each object to the queue. When an object changes state, add the object to each user's queue, if the object isn't already in the queue. N times a second, for each user, remove the next X/N objects out of the queue and send their state to the client. This is pretty simple to get going, but may let object updates "jump ahead" in the queue, so a partially received state may be different for different users.
enum Bool { True, False, FileNotFound };
I appreciate your reply hplus, but I couldn't understand your second paragraph.
I have never considered a user could have an inconsistent view of the server. I don't see how would that work. Care to explain?



I appreciate your reply hplus, but I couldn't understand your second paragraph.
I have never considered a user could have an inconsistent view of the server. I don't see how would that work. Care to explain?


For example, suppose there is a red halo around a user when using an attack boost spell.
On the server, player A casts attack boost on player B, then player B attacks monster C.
Because of re-ordering, the order of update I see on the screen might be:
1) Player B attacks monster C.
2) Monster C takes attack damage equal to the boosted damage.
3) Player B receives the red halo from the boost spell.

Exactly how display of different actions and their effects happens in a particular game is often a very carefully tuned set of rules based on the specific needs of the particular game mechanic. For some games, the exact order has to happen for all players -- typically, RTS games will do this. However, then you run into problems with late joiners, everyone needing to see all the data, etc.
enum Bool { True, False, FileNotFound };
Okay. I don't think this works for me though.

The way I'm going to solve this for now is to reduce the thread pool for processing and dispatching to a single thread. This way all the operations that mutate the server state are thread-confined and thus do not need locking. There's no more danger another thread will mess up the data when I'm creating a snapshot. And there's no more danger the newcomer, by the action of some other thread, will begin to receive updates before he got the initial snapshot. All the events generated by the reader thread will bubble up in the event dispatch queue and wait there until the dispatcher thread finished dealing with the snapshot and is ready to process them. I need to test scalability and performance of all of this though.

This topic is closed to new replies.

Advertisement