How to Get Rufus-Scheduler Working with a Rails App Deployed to Heroku

How to get rufus-scheduler working with a Rails app deployed to Heroku?

Here's an example of how to get it to work on Rails:

#
# config/initializers/scheduler.rb
require 'rufus-scheduler'

# Let's use the rufus-scheduler singleton
#
s = Rufus::Scheduler.singleton

# Awesome recurrent task...
#
s.every '1m' do
Rails.logger.info "hello, it's #{Time.now}"
end

Take a look at the documentation.

Make rufus-scheduler work on Heroku

You can do this, but you have to understand how hobby dynos work. each free account is allocated hours like this.

Accounts are given a base of 550 hours each month in which your Free dynos can run. In addition to these base hours, accounts which verify with a credit card will receive an additional 450 hours of Free dyno quota.

Because rufus-scheduler runs as a thread in your ruby app process (this is why it starts running when you run rails console), as long as you have your server (I use puma) running, rufus scheduler will run just fine.

The downside is that if you run two processes in your server, say you run puma with 3-4 workers, you're going to have 3-4 of your schedulers running at the same time making it execute your scheduled events in triplicate/quadruplicate, so keep that in mind as well.

So the steps are simple
- make sure you have enough hours to run your dyno continuously all month
- use a service like pingdom, to ping your app every couple of minutes to keep the dyno active so that Heroku doesn't spin it down after 30 minutes of inactivity (it does that to free dynos)
- that should be all you need to do

Just remember that to run a dyno for a month you're going to need about 745 hours which your primary allocation covers (when you add a credit card). If for some reason you run out of hours (say you run two different apps on the account and use the method I describe below) then this could happen to you

A second notification will be sent when you reach 100% of your account quota, at which point your application’s dynos will be put to sleep for the remainder of that month. As a result, any apps using free dynos will not be accessible for the remainder of the month.

Seems like a lot of trouble to go to when you can just use the heroku scheduler to schedule rake tasks like everyone else does.

How can I schedule a 'weekly' job on Heroku?

One approach would be the one of your 2nd bullet point:

activate the Heroku cron add-on, and add a cron.rake task in app/lib/tasks

Activate the Heroku scheduler add-on, and add a scheduler.rake task in app/lib/tasks

task :your_weekly_task=> :environment do
if Time.now.friday? # previous answer: Date.today.wday == 5
#do something
end
end

You even have the luxury of defining the day you want your task to run ;o)
(5 is for Friday)

EDIT: by the way, Cron is deprecated and Heroku recommends switching to their Scheduler add-on. This doesn't change the approach for a weekly job though.

EDIT2: adjustments to my answer based on feedback from sunkencity.

how can i call a dynamic scheduler to call a method to get tweets several times in a day with rufus-scheduler and Rails 4

Simplify your controller to:

class FeedsController < ApplicationController
def index
@tweets = Feed.latest
end
end

Then make sure you have a config/initializers/scheduler.rb that looks like:

require 'rufus-scheduler'

Rufus::Scheduler.singleton.every('60s') { Feed.pull_tweets }

So that you have a single scheduler for the whole Ruby process.

To answer your question:

require 'rufus-scheduler'

Rufus::Scheduler.singleton.cron('0 1,9,15 * * *') { Feed.pull_tweets }
# pull tweets at 0100, 0900 and 1500

Your code is creating a rufus-scheduler instance each time a browser GETs /feeds, the code here has a single scheduler.



Related Topics



Leave a reply



Submit