Imagine and application like Whatsapp that for each chat has a count of mentions and messages not read:
I want to implement a scalable system to handle notification count of an app. Here what I've think about possible solutions and their problems:
1) Create a counter for each user in each group collection and increase by 1 for each new message:
➜ Problem: if I have chats with 500, 1000, 10000 users I will have to do 500, 1000, 10000 field updates.
➜ Test: I've created a new collection with 50M of documents. Update time for 6000 users = 0.15 seconds. Update time for 100000 users = 14.2 seconds. It's not scalable.
Notifications Model: (compound index: roomId: 1, channelId: 1, userId: 1)
{
roomId: string,
channelId: string,
userId: string,
unread_messages: int,
unread_mentions: int,
last_read: date
}
2) Save the last message read from each user and when doing the initial data GET, count for each chat, from the last message read to the last, and limit it.
➜ Problem: if you have 200 chats and you limit the number of notifications to 100 and it has been a while without logging into the application, you will have to count 100 * 200 rooms. When the "Count" operation is quite expensive for databases.
➜ Test: I've counted 100 messages per chat and 200 chats = 8.4 seconds. Messages indexed by id and timestamp. A lot of time for client login.
3) Set up a PUB / SUB using for example ActiveMQ, RabbitMQ or Kafka, and for each chat create a queue.
➜ Problem: You duplicate messages in the database and in queue/topics, in addition to being shared queues you would have to make queries if I am user X up to where I have read the last time and when you connect as a subscriber those messages are consumed and they are no longer available to other consumers. In kafka, if each topic it's a chat, I can't do a count of pending notifications without getting all pending messages and consuming them. So, if I consume this messages and I dont enter in a chat, there will be no notifications the next time I log in.
Can you think of any more options or are any of the ones I mentioned previously are scalable?
Thank you very much in advance.
