Reputation: 2729
I'm building a Meteor.js application where events are displayed in a calendar.
Part of the functionality is that the application will automatically remind users in advance of the event by email. This is easy enough with a fixed reminder period (say 3 days or so) but I need to build a system where the user can choose their notification interval. So it could be 3 days, 7 days, 3 hours, 24 hours etc etc.
I can set up a cron job that searches through the events collection and checks if the event date - 3 days > current date
, then ping off a notification, but I'm not sure how to make this cron job if each user has a custom interval.
The way I am thinking of handling it right now, is that the event is saved with two values: the date
and the reminderDate
. When the event is saved to the database, the reminderDate
is calculated based on the interval that the user has chosen. Then, if they update their reminder settings from say 24 hours to 1 week, an operation will be performed that will update the reminderDate
of all of their events.
The problem with the above solution is that if they have hundreds or thousands of events in the DB, that could be a really long operation that takes quite a while to complete. There must be a better way?
Any advice about how to handle this would be much appreciated!
Upvotes: 1
Views: 1239
Reputation: 20227
There are a couple ways to go about this and it's probably a matter of opinion as to which is best, especially without more information about the number of events, the number of users, and the frequency with which a user might update their notification preference.
If a user only updates this preference rarely (typical) then your approach of storing the notification date is appropriate. You only have to update future events, not past ones so that can reduce the scope of changes.
Another approach can be sufficient if the number of possible reminder intervals are limited. In your example you have 24 hours to a week. Suppose we say the possible intervals are:
const intervals = [1,2,3,4,5,6,7]; // days
Then in your daily cron job you can just iterate over these intervals and look for any events that match now + interval and alert on those.
let start = new Date();
intervals.forEach(interval => {
const end = start.setHours(start.getHours()+24*interval);
Events.find({date: {gte: start, lt: end}}).forEach(event => {
// send notification for each event in the interval
});
start = end; // move the start time to the beginning of the next interval
});
Upvotes: 1