I want to enable some real-time notifications about friend's activities (social network).
Technical context is: Webapp calling backend (REST API's).
Kevin follows Bob.
When Bob posts a new comment, Kevin should be notified immediately (near real-time).
Besides, when Kevin logs in, he should be able to see some past notifications, similar to what Facebook does.
Meaning that notifications should be stored somewhere.
Here's the technical workflow:
- Bob posting a new comment involves an insert in database of this new comment.
- As following Domain-Driven-Design, the event
- A distinct worker in the same bounded context (long-running process, polling the database each second) listening to this event captures it.
At the end of 3, I see 2 possibilities:
- Creating the corresponding notification, storing it in database and THEN sending it to Redis Pub/sub. This one would feed some specific subscribers acting on the WebSocket connection to send the notification to Kevin's client.
- Creating the corresponding notification, then sending it to Redis THEN storing them in database.
Regarding the first possibility, the advantage would be the transactional aspect. Indeed, no noticification could be sent if it wasn't saved before. => Integrity.
However, the drawback is that the database insertion could slow down the process of "near real-time notification".
Regarding the second possibility, notifications are immediately sent but if some failure happens regarding database insertion, Kevin might have wondered:
"Humm... I received the Bob's notification, I'm sure I saw it. So why a simple page refresh doesn't show it anymore?" => Indeed, it wasn't persist successfully, so can't query it.
What is a good practice regarding this use case?
Of course, one faster way would be to not involve an event listener for this case, but it would violate some principles regarding Domain-Driven Design. IMHO, listener polling database in its own bounded context is necessary. (evoked by Vaughn Vernon in this book IDDD - "Building an event store")