List functional requirements for the system (Ask the chat bot for hints if stuck.)...
users should be able to search for opponents and play matches
Validate users moves
Maintain the state of the game
Guarantee user authentication to ensure correct users stays in the game and avoid Man in the middle attacks
List non-functional requirements for the system...
Latency - near real time moves < 100ms
Scalable - Should be able to handle millions of users - 1 million DAU
Consistency—Player moves need to be consistent
Durable - Moves should remain even after a server restart
Estimate the scale of the system you are going to design...
1 m DAU = 1million /100k = 10 requets per second
Define what APIs are expected from the system...
Search Games
Look Up Games - GET /get_games/?region, type
Send Challenge - POST /send_challenge/
{
game_id
text
}
Accept game - POST
{
decision
game_id
}
Make moves
{
piece
move_to
}
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
User
username
region
level
Match
player1(always white)
player2
ranked
level
winner
board - dictionary of all pieces and their position on the board
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
User requests using the search games api to to get all the available games / matchups. Use can then use the challenge api to send challenge request to get a match up with the game_id from the search_games api response
User can make oves using the make_move api with the piece type and the move to make it to , our server can then validate the move and move it
We can use write through strategy and write the move to our cache and database
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
To make the moves as real time as possible we can use sockets, with Redis cache to keep a track of the moves, we can use AOF persistence with redis to ensure durability in case of redis failure and with a write back strategy to keep it in database . We can then establish a websocket connection between the users and the server to keep it real time
For scaling to millions of users we can use a zookeeper ring to keep a record of which server each user is connected to and where to route them to.
For keep a real time leader board we can make use of a redis sorted set
Explain any trade offs you have made and why you made certain tech choices...
Redis for storing game moves can cause cause loss of data if it goes down
Websockets can cause higher complexity and require sticky sessions.
Try to discuss as many failure scenarios/bottlenecks as possible.
Redis crash for storing games moves can cause data loss
Websockets with sticky sessions are needed in order to maintain real time game
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?