rufus-scheduler and delayed_job on Heroku: why use

2019-04-09 03:03发布

问题:

I'm developing a Rails 3.2.16 app and deploying to a Heroku dev account with one free web dyno and no worker dynos. I'm trying to determine if a (paid) worker dyno is really needed.

The app sends various emails. I use delayed_job_active_record to queue those and send them out.

I also need to check a notification count every minute. For that I'm using rufus-scheduler.

rufus-scheduler seems able to run a background task/thread within a Heroku web dyno.

On the other hand, everything I can find on delayed_job indicates that it requires a separate worker process. Why? If rufus-scheduler can run a daemon within a web dyno, why can't delayed_job do the same?

I've tested the following for running my every-minute task and working off delayed_jobs, and it seems to work within the single Heroku web dyno:

config/initializers/rufus-scheduler.rb

require 'rufus-scheduler'
require 'delayed/command'

s = Rufus::Scheduler.singleton
s.every '1m', :overlap => false do # Every minute
  Rails.logger.info ">> #{Time.now}:  rufus-scheduler task started"
  # Check for pending notifications and queue to delayed_job
  User.send_pending_notifications
  # work off delayed_jobs without a separate worker process
  Delayed::Worker.new.work_off  
end

This seems so obvious that I'm wondering if I'm missing something? Is this an acceptable way to handle the delayed_job queue without the added complexity and expense of a separate worker process?

Update

As @jmettraux points out, Heroku will idle an inactive web dyno after an hour. I haven't set it up yet, but let's assume I'm using one of the various keep-alive methods to keep it from sleeping: Easy way to prevent Heroku idling?.

回答1:

According to this

https://blog.heroku.com/archives/2013/6/20/app_sleeping_on_heroku

your dyno will go to sleep if he hasn't serviced requests for an hour. No dyno, no scheduling.

This could help as well: https://devcenter.heroku.com/articles/clock-processes-ruby