views:

32

answers:

2

I have a rails app deployed on Heroku. I want to add a feature that enables users of the app to set a reminder. I need some way for the app to schedule sending an email at the time specified by the user.

I have found numerous posts referring to using delayed_job for this, but none of the write-ups / tutorials / etc. that I have found directly address what I am trying to accomplish (the descriptions I have found seem more geared towards managing long-running jobs that are to be run "whenever").

Am I on the right track looking at delayed_job for this? If so, can somebody point me towards a tutorial that might help me?

If delayed_job is not quite right for the job, does anybody have a suggestion for how I might approach this?

+1  A: 

The most typical way of handling this is to use a cron job. You schedule a job to run every 15 minutes or so and deliver any reminders that come up in that time. Unfortunately, heroku only allows cron jobs to run every hour, which usually isn't often enough.

In this case, I'd use delayedjob and trick it into setting up a recurring task that delivers the notifications as often as necessary. For example, you could create a function that begins by rescheduling itself to run in 10 minutes and then goes on to send any reminders that popped up in the previous 10 minutes.

To view delayedjobs send_at syntax to schedule future jobs check here: http://wiki.github.com/tobi/delayed_job/

ADDED after comments: To send the reminder, you would need to create a function that searches for pending reminders and sends them. For example, let's say you have a model called Reminder (rails 3 syntax cause I like it better):

def self.find_and_send_reminders
 reminders = Reminder.where("send_at < ? AND sent = ?", Time.now, false).all
 reminders.each do |r|
   #the following delayed_job syntax is apparently new, and I haven't tried it.  came from the collective_idea fork of delayed_job on github
   Notifier.delay.deliver_reminder_email(r)
   #I'm not checking to make sure that anything actually sent successfully here, just assuming they did.  may want to address this better in your real app
   r.update_attributes!(:sent => true)
 end
 #again using the new syntax, untested.  heroku may require the old "send_at" and "send_later" syntax
 Reminder.delay(:run_at => 15.minutes.from_now).find_and_send_reminders
end

This syntax assumes you decided to use the single reminder entry for every occurence method. If you decide to use a single entry for all recurring reminders, you could create a field like "last_sent" instead of a boolean for "sent" and use that. Keep in mind these are all just ideas, I haven't actually taken the time to implement anything like this yet so I probably haven't considered all the options/problems.

Ryan
I think am following you. I guess I'm still not quite sure how to model this behavior in my application. I want users to set reminders along the lines of "once a day until I do something to turn the reminder off" or "one time only at a certain time." Any tips on how to do this?I have been combing the Internet for a tutorial or blog post that addresses this type of thing, but no luck...
eksatx
Well, this is really a multiple part question. You need to A) parse the request and store the reminder correctly B) Handle the recurring aspects (do you store one DB record that just says "do this every month" or schedule a new db record every month that says "do this once") and C) create a function that locates those DB records and send the email. I'm going to address C b/c that's what you asked. Editing my original answer so it's easier to read.
Ryan
Thanks for fleshing this out. I think the approach of having a field to describe the recurrence (perhaps using runt, once I figure out how to use it) and a last_sent_at field might do the trick. The sample code is very helpful. I'll play with this in the coming week...
eksatx
+1  A: 

Check out the runt gem, may be useful for you: http://runt.rubyforge.org/

tfe