Reputation: 23747
My goal is to have a main app adding jobs to a Resque queue on Heroku. However, I want the workers to be run in different apps.
Can I enqueue a job in an app to be performed by other app(worker)? Is there any tutorial explaining how to do it?
Thanks
Upvotes: 0
Views: 661
Reputation: 5570
This takes care of the environment, usually on Heroku you run with RedisToGo:
# config/initializers/resque.rb
uri = if ENV['REDISTOGO_URL']
URI.parse(ENV['REDISTOGO_URL'])
else
Settings.redis.uri
end
Resque.redis = Redis.new(host: uri.host, port: uri.port, password: uri.password)
Remember that if you are using the Cedar stack you must write in your Procfile:
worker: bundle exec rake environment resque:work
As a added bonus, in your Gemfile gem 'heroku'
and put this in lib/heroku_resque_auto_scale.rb and require the file from your resque initializer:
require 'heroku'
module HerokuResqueAutoScale
module Scaler
class << self
@@heroku = Heroku::Client.new(ENV['HEROKU_USER'], ENV['HEROKU_PASS'])
def workers
@@heroku.info(ENV['HEROKU_APP'])[:workers].to_i
end
def workers=(qty)
@@heroku.set_workers(ENV['HEROKU_APP'], qty)
end
def job_count
Resque.info[:pending].to_i
end
end
end
def after_perform_scale_down(*args)
# Nothing fancy, just shut everything down if we have no jobs
Scaler.workers = 0 if Scaler.job_count.zero?
end
def after_enqueue_scale_up(*args)
[
{
:workers => 1, # This many workers
:job_count => 1 # For this many jobs or more, until the next level
},
{
:workers => 2,
:job_count => 15
},
{
:workers => 3,
:job_count => 25
},
{
:workers => 4,
:job_count => 40
},
{
:workers => 5,
:job_count => 60
}
].reverse_each do |scale_info|
# Run backwards so it gets set to the highest value first
# Otherwise if there were 70 jobs, it would get set to 1, then 2, then 3, etc
# If we have a job count greater than or equal to the job limit for this scale info
if Scaler.job_count >= scale_info[:job_count]
# Set the number of workers unless they are already set to a level we want. Don't scale down here!
if Scaler.workers <= scale_info[:workers]
Scaler.workers = scale_info[:workers]
end
break # We've set or ensured that the worker count is high enough
end
end
end
end
Credit: https://gist.github.com/812430
Upvotes: 0
Reputation: 1813
Resque is going to use whatever Redis instance you point it at. In Heroku, that's probably going to be an instance from the separate service Redis To Go. You just need to write your Resque setup code to point to the common Redis instance.
From http://blog.redistogo.com/2010/07/26/resque-with-redis-to-go/
uri = URI.parse(ENV["REDISTOGO_URL"])
Resque.redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
This will initialize Resque with the environment variable, which you can set in each deployed Heroku app using heroku config:add REDISTOGO=etc.
Upvotes: 1