List functional requirements for the system (Ask the chat bot for hints if stuck.)...
List non-functional requirements for the system...
Estimate the scale of the system you are going to design...
10M total users
Daily Active Users(DAU) = 1M
Number of logged in users at any time = 10K
Incoming messages of hearbeat = 10K per second
Data Storage of Active and Idle Users only. Data storage required = 1M * 100 bytes = 100 MB. Data is in-memory only.
Define what APIs are expected from the system...
Get the online status of a user
GET https://
User posts the hearbeat periodically
POST wss://
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...
Online Presence Service is stateless. Data resides in the caches only.
Data in Activity Cache:
user id
Timestamp
Data in Heartbeat Cache:
user id
Heartbeat
Activity Cache is used to determine when the user was actively running operations on the system. It is used to indicate the 'active' status.
Heartbeat Cache is used to determine if the user is logged in. A user can be logged in but not performing any activities on the system. In this case, her status is 'idle'.
If none of the caches are update for a pre-determined time, say 10 mins, the web socket connection or long-polling connection is closed and user's status = offline.
Redis or any other caching solution can be used.
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...
User: Interacts with our service, performs operations and sends heartbeats
Heartbeat Server: Accepts heartbeats from the user. Heartbeat is updated in the Heartbeat cache.
Heartbeat Cache: Stores tuples of
API Server: Used for servicing other business-related apis. User id performing the activity and timestamp are logged in Activity Cache
Activity Cache: Stores tuples of
Presence Calculator: Combines data from Heartbeat and Activity caches to determine user's status.
If activity performed within timeout ==> user is active
If Heartbeat received but no activity in the timeout window => user is idle
No heartbeat of activity observed for timeout period => user is offline
Notification Service: Receives status/presence data from the Presence calculator. This data is shared with devices or any other services which require it
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: Interacts with our service, performs operations and sends heartbeats
Heartbeat Server: Accepts heartbeats from the user. Heartbeat is updated in the Heartbeat cache.
Heartbeat Cache: Stores tuples of
API Server: Used for servicing other business-related apis. User id performing the activity and timestamp are logged in Activity Cache
Activity Cache: Stores tuples of
Presence Calculator: Combines data from Heartbeat and Activity caches to determine user's status.
If activity performed within timeout ==> user is active
If Heartbeat received but no activity in the timeout window => user is idle
No heartbeat of activity observed for timeout period => user is offline
Notification Service: Receives status/presence data from the Presence calculator. This data is shared with devices or any other services which require it
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...
Web Sockets or long polling for Heartbeat monitoring. As heartbeats are sent periodically, using long polling of web sockets reduces the overhead of re-establishing connection every time a heartbeat is sent.
Explain any trade offs you have made and why you made certain tech choices...
If no heartbeat or activity is received for 10 mins, the user is considered offline and web-socket or long-polling connection to her is closed. This saves resources. However, if the user was logged in, it will automatically log her off.
Presence Calculator reads data from Heartbeat and Activity cache every 5 mins. So data reported by it may be stale by 5 mins. This is a tradeoff between aggressive reading/calculation and reporting stale data.
Try to discuss as many failure scenarios/bottlenecks as possible.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?