I have a Sidekiq worker that is intended to perform social actions (e.g.: like pages on Facebook). Part of this requires knowing the URL for the object being liked.
Fortunately, Rails 3 makes it easy to access app-specific routes by including Rails.application.routes.url_helpers
in whatever class or module needs access to the path/url helper method.
The problem I'm running into is that my default url/port are not accessible from within my Sidekiq worker despite various attempts to define them in my development.rb
or production.rb
.
class Facebook::LikeRecipeWorker
include Sidekiq::Worker
include Rails.application.routes.url_helpers
sidekiq_options queue: :facebook
def perform(recipe_id, user_id)
recipe = Recipe.find(recipe_id)
user = User.find(user_id)
if user.facebook_token
api = Koala::Facebook::API.new(user.facebook_token)
api.put_connections 'me', 'my_namespace:like', object: recipe_url(recipe)
end
end
end
When the recipe_url
method is access, an ArgumentError
is raised with the message:
ArgumentError: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
I know that I can specify default_url_options
for ActionController
or ActionMailer
in the environment-specific config files, e.g.:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_controller.default_url_options = { host: 'localhost', port: 3000 }
However, these (rightfully) appear to have no influence on my Sidekiq worker classes. How should I go about defining default_url_options
for these classes?
Sidekiq depends on Redis to communicate between the Rails server process and the background workers. Follow the Redis setup guide to provision a Redis server and set a REDIS_URL within the Rails app. Be sure to set the REDIS_URL via a secret as demonstrated in the Redis documentation.
The author of Sidekiq recommends a limit of 1,000 jobs per bulk enqueue and that's the default in the perform_bulk method. Even then you are saving the time of 999 round trips to Redis.
Workarea applications use Sidekiq as a job queuing backend to perform units of work asynchronously in the background. These jobs, which include search indexing, cache busting, and cleanup of expired data, are defined as workers .
What we did was this:
In your config file(s) (e.g. config/application.rb, config/production.db, etc.), have a line that sets the default:
routes.default_url_options = { host: 'www.example.org' }
I found a potential solution to this, though it feels like a little bit of a hack. I'm definitely open to better answers.
First, in my environment files (e.g.: config/environments/development.rb
), I specify the default_url_options
for my controllers:
config.action_controller.default_url_options = { host: 'localhost', port: 3000 }
Then in my worker class, I define a default_url_options
instance method there:
class Facebook::LikeRecipeWorker
# ...
private
def default_url_options
ActionController::Base.default_url_options
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With