List the key functional requirements for the system (Ask the AI for hints if stuck)...
User should be able to:
List the key non-functional requirements (performance, scalability, reliability, etc.)...
Define the APIs expected from the system. This is your chance to analyze and define the read and write paths so that you can come up with the high-level design...
WS /api/v1/message
POST /api/v1/Notify
POST /api/v1/CreateGroup
POST /api/v1/JoinGroup
DELETE /api/v1/DeleteGroup
CDN: It is used to host the frontend of the service. The response is fast because it is in edge locations. Most of the time it handles 80% of the reads since it can cache as well. Media is also served using CDN only
API Gateway: To route traffic based on the endpoint getting hit. Used for authentication and for rate limiting the requests.
Kafka: It is used as a high throughput queue to store the requests that are received. With this even if there is a down time it is easy to recover as kafka will have the missed requests. User will receive 200 OK
Redis:To cache the requests and take care of concurrent redundant requests and reduce load on the db and response time. and to store sorted sets so that delivery is fast.
Blob Storage: Great way to store the media that is uploaded into the platform we can use services like S3 for this.
Mongo: Document DB used for this use case.
Message Service: It is used to send and receive message. Uses Websockets to keep the messaging real time. When ever a message event occurs it sends that to Kafka topic which in turn used by notification service.
Notification Service: Used to send notification to subscribers.
Group Service: Handles all the Group related operations.
Connection Manager: Handles all the connections and this is where the persistent connection actually lives.
resume path: client reconnects with last_message_id → service replays missed messages from the log/DB.
Define the data model. Identify the main entities, their attributes, and relationships. Consider the choice of database type (SQL vs NoSQL) and justify your decision based on access patterns...
We'll be using MongoDB
Group:
ID
Name
Members - Points to user with group id
CreatedAt
Visibility - public/private
UpdatedAt
Users
ID
Name
CreatedAt
UpdatedAt
GroupMembers
GroupID
UserID
For messaging we'll be using cassandra. Will be sharded based on groupID.
Message:
ID
UserID
GroupID
Text
Attachments
timestamp
For storing the attachments we can use blob storage like s3
If a action fails we even retry it for a set amount of times lets say 3. If it fails more than that set limit it will go to the DLQ. We will be retrying using exponential backoff with jitter to avoid multiple retries at the same time. This will prevent any load on the respective service.
We will be having replicas to adhere to high availability so that when ever a service fails it's replica takes over. We can go even further by having regional failovers so that if a region goes down we can switch to the other region.
client disconnects, reconnects with last_message_id, node replays missed messages from the log/DB.
Kafka partition key = group_id, so a conversation's messages stay ordered even with retries and multiple consumers
connection map in Redis lets any node rebind the session; no sticky-socket dependency.