tl;dr - Notifications have been completely changed on Allotrop. Rather than simple messages, you now get full fledged notifications on a separate page. This post talks about the technical changes under the hood.
Notifications was one of the earliest code that I wrote for Allotrop back in January this year and also one of the most ugly ones. Since then, Allotrop has gone through iterations and it was time to evolve the notifications code. Some of the assumptions that I remember I had back in January:
Notifications need to be stored only for a short time.
I need to have data formatted in such a manner that I do not need to do much processing while rendering. For example, if 4 users have reposted your post, I was storing the ids of user 1, user 2 ( the last 2 users to add your post) and the number 2 as count-suffix.
I also wanted to show the notifications as a popout on every page when the user clicks on the notification count. Notifications were rendered in a div hidden by default whose content was added to the popout's content on initialization.
Unseen notification were determined by the timestamp of the last seen notification.
I was using a Redis set for each user as the notification queue. Each member of this set pointed to a hash or a sorted set (in case of follow notifications). I was using Sidekiq background workers to update this hash/sorted set. This is directly from the source some time back.
Old Notification screenshot
I was doing so many things wrong. I was maintaining a count of reposts for every post in redis and using that count to generate the notifications. This was a relic of the old linear programming model. As I soon found out the background workers give no assurance that they will execute in the same order that they are called. Since Allotrop never reached significant volume, the effects were negligible. Otherwise, the notifications would have been hugely erratic. The way I was storing data also had to do a lot with how they were supposed to be rendered. Never a good idea.
But, with the relaunch of Allotrop, notifications had to be redone. I had the following objectives in mind this time:
Notifications were now supposed to be stored persistently.
New kind of notifications should not need huge work. I was never able to get comment for a post to go to people who have commented previously. This made sure comment threads never took off.
Notifications should be more full fledged. The user should see the complete post rather than just link to it.
Unseen notifications are now determined by the id of the last seen notification rather than the timestamp of the notification.
I now use a Notification model. This has belongs_to relationships with the user and post model. There is a category field which contains the type of notification and a hstore for everything else. The current notification model:
I would love to get any suggestions on how I can further improve this code. Enjoy your notifications.
Photo: Physical Notifications - Flickr/johanl