0

I am considering CQRS for building a realtime game server (not gameplay but the economy).

For some reasons. Scaling, Event logging, Model changing.

However in realtime game when player upgrade, for example character. I mocked the client without need any server feedback.

But if he close the game immediately after upgrade and quickly reopen the game, He MUST saw his character upgraded.

Question:

  1. I'm wonder how much read model delayed? What reason(s) cause it for delay? If I have only little preprocessing process data for read model. I have no experience at scale.

  2. Is CQRS still ok for this use case?

  3. If it still ok, What options should I choose here?

    3.1. Block user from reading until the read model finished update.

    3.2. Block user from reading at the beginning that command reached server until the read model finished update.

    3.3. Guarantee read model update time to be lesser than application opening time. And ignore these issue.

  • 1
    What purpose will CQRS have in your game? What role will it play? What practical problem will it solve? – Robert Harvey Jun 23 '18 at 21:10
  • @RobertHarvey CQRS is act as my coreloop system (buying, selling, upgrading etc.). As I mentioned my purpose is to achieve event logging, global scaling and read model change in order. Frankly I also don't see enough benefit from pure CQRS, However It's win when having ES. The read side is what client need just once when open the app and have to be consistence. – b.ben Jun 24 '18 at 2:06
3

I'm wonder how much read model delayed? What reason(s) cause it for delay? If I have only little preprocessing process data for read model. I have no experience at scale.

"It depends." The cause of the delay is the propagation of the information from the data structure that supports the write to the data structure that provides the read. So some of the difference is in the distance between the two data structures, some in how much work is required to fold the new information into the read model, and how much time there is between the write, and the start of the process to copy that information to the new data structure.

Another way of thinking about this is that the "clock" of the read model runs slow compared to the write model; so the read model is describing what things look like "now", where now is some time in the past.

So one thing that you can do in some cases is to make that clock explicit; "show me what the model looked like at time = t"; or "show me a recent model after time = t" is a query that the client can send to a read through cache; where the query handler can simply look to see if its copy is recent enough to satisfy the query, and if not pull a more recent copy of the data.

We say "read model" and "write model", but fundamentally there's nothing wrong with reading data from the write model -- identify the most recent write model available at the time of the query, and then (synchronously) build a representation of the query response, to return. That gets you a more "recent" version of the read model, at the cost of some extra time processing the query.

Also, you don't have to use the same caching strategy for all queries; for instance, you might use a cached read model when showing a user somebody else's character, but using a fresh read model when showing a user their own character.

Part of the point of CQRS is that you can make these decisions on a case by case basis.

  • Sounds reasonable. Could "reading from the write model" simply be a status returned from the write method being called? – Robert Harvey Jun 24 '18 at 1:39
  • There are additional options if the restarted instance of the client still has access to the response from the server. – VoiceOfUnreason Jun 24 '18 at 2:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.