Delayed extensions - rselk/sidekiq GitHub Wiki
Delayed extensions allow method calls to be executed asynchronously. By default, all class methods can be executed asynchronously. In Rails application, you can make ActiveRecord method calls and ActionMailer deliveries asynchronous.
ActionMailer
Use delay
to deliver your emails asynchronously. Use delay_for(interval)
or delay_until(time)
to deliver the email at some point in the future.
UserMailer.delay.welcome_email(@user.id)
UserMailer.delay_for(5.days).find_more_friends_email(@user.id)
UserMailer.delay_until(5.days.from_now).find_more_friends_email(@user.id)
You can also easily extend the devise gem to send emails using sidekiq.
ActiveRecord
Use delay
, delay_for(interval)
, or delay_until(time)
to asynchronously execute arbitrary methods on your ActiveRecord instance or classes.
User.delay.delete_old_users('some', 'params')
@user.delay.update_orders(1, 2, 3)
User.delay_for(2.weeks).whatever
User.delay_until(2.weeks.from_now).whatever
I strongly recommend avoiding delaying methods on instances. This stores object state in Redis which can get out of date, causing stale data problems.
Class Methods
Any class method can be delayed via the same methods as above:
MyClass.delay.some_method(1, 'bob', true)
Just remember to keep the method arguments simple, don't pass complex Ruby objects.
Advanced Options
You can tune the worker options used with a .delay
call by passing in options:
MyClass.delay(:retry => false).some_method(1, 2, 3)
MyClass.delay_for(10.minutes, :retry => false).some_method(1, 2, 3)
Disabling Extensions
The delay extensions can conflict with DelayedJob if you want to run both in the same process. You can disable them in a Rails application by calling Sidekiq.remove_delay!
in an initializer. This will prevent the delay extension modules from ever being loaded. If you would like to include the delay extensions prefixed with sidekiq_
(i.e., sidekiq_delay
, sidekiq_delay_for
and sidekiq_delay_until
), call Sidekiq.hook_rails!
first in your initializer:
# config/initializers/sidekiq.rb
# Sidekiq.hook_rails! # uncomment if you want the delay extensions, but prefixed with `sidekiq_`
Sidekiq.remove_delay!
If you are using Sidekiq outside of a Rails application, the class method extensions are always loaded.
Troubleshooting
The delay extensions use YAML to dump the entire object instance to Redis. The psych
engine is the only supported YAML engine; this is the default engine in Ruby 1.9. If you see a YAML dump/load stack trace, make sure syck
is not listed.
Objects which contain Procs can be dumped but cannot be loaded by Psych. This can happen with ActiveRecord models that use the Paperclip gem. IMO this is a Ruby bug.
o = Object.new
o.instance_variable_set :@foo, Proc.new { 'hello world' }
yml = YAML.dump(o) # works!
YAML.load(yml) # BOOM