sucker_punch-backgroundable
This gem allows you to background any method call with Sucker Punch without having to write a special job class. It provides the same API as the Backgroundable module from TorqueBox, and a large part of the code comes directly from the TorqueBox project.
Installation
Add the following to your Gemfile:
gem 'sucker_punch-backgroundable'
And then execute:
bundle install
Versions
The Sucker Punch API changed when Sucker Punch 2.0 was released. This gem uses the new API and requires Sucker Punch 2.0 (or higher). If for some reason you have to use an older version of Sucker Punch, please use version 0.2.0 of this gem.
Usage
Include the SuckerPunch::Backgroundable
module in your class. Then you can use always_background :method1, :method2, ...
to
cause the supplied methods to run asynchronously in the background ("fire and forget"). Example:
class MyClass
include SuckerPunch::Backgroundable
always_background :send_email
def send_email
# ...
end
always_background :calculate_statistics
def self.calculate_statistics
# ...
end
end
In this example, calls to instance method send_email
and class method calculate_statistics
will automatically run in the background:
obj = MyClass.new
obj.send_email # returns immediately, method runs in the background
Myclass.calculate_statistics # returns immediately, method runs in the background
Methods that have not been marked with always_background
can also be backgrounded when you call them:
class MyClass
include SuckerPunch::Backgroundable
def notify
# ...
end
end
obj = MyClass.new
# This will run in the background (and return immediately)
obj.background.notify
# This will run the method normally (synchronously, returning after the method is finished)
obj.notify
It is also possible to specify a delay in seconds:
# This will return immediately and run the method in the background after a delay of 60 seconds
obj.later(60).notify
Both background
and later
also work with class methods (e.g. MyClass.background.my_class_method(argument)
).
Reloading
When backgrounding an instance method, the method is called on the object, but in a different thread (using SuckerPunch). If you don't use the object anymore in the current thread, this is ok. If the object is still being used in the current thread, it may be better to reload it from the data store (assuming a data store backed object) in the background thread to avoid any threading issues. The gem can do this automatically, although currently only ActiveRecord is supported:
class MyModel < ActiveRecord::Base
include SuckerPunch::Backgroundable
always_background :send_email, :reload => true
def send_email
# ...
end
end
Or, when using background
or later
:
obj.background(:reload => true).my_instance_method
obj.later(60, :reload => true).my_instance_method
It is also possible to specify the reload
option globally by using an initializer:
SuckerPunch::Backgroundable.configure do |config|
config.reload = true
end
Configuration
Apart from the reload
option described above, there are two other configuration settings:
SuckerPunch::Backgroundable.configure do |config|
config.reload = true
config.workers = 4 # default is 2
config.enabled = true
end
The number of workers sets the number of background threads that SuckerPunch will use. The default (and minimum) is 2.
By setting enabled to false, backgrounding is globally disabled, so all methods will be executed synchronously. This can be useful in tests.
Usage with ActiveRecord
When using this gem with ActiveRecord models, it is recommended to set the reload
option to true (see above).
If you want sucker_punch-backgroundable to be available in all models you can use the following in an initializer:
ActiveRecord::Base.send(:include, SuckerPunch::Backgroundable)
Switching from TorqueBox Backgroundable
This gem is completely independent from TorqueBox (or JRuby). But if you are already using TorqueBox Backgroundable, you can switch to backgrounding with SuckerPunch by a simple change in an initializer:
# In config/initializers/active_record_backgroundable.rb, replace
if defined?(TorqueBox::Messaging::Backgroundable) && defined?(ActiveRecord::Base)
ActiveRecord::Base.send(:include, TorqueBox::Messaging::Backgroundable)
end
# by this:
ActiveRecord::Base.send(:include, SuckerPunch::Backgroundable)
Switching from TorqueBox Backgroundable to SuckerPunch will save you RAM (since TorqueBox uses a separate application instance for Backgroundable), but remember that SuckerPunch jobs are not persisted, so you might lose jobs on a server restart.
Contributing to sucker_punch-backgroundable
- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
- Fork the project.
- Start a feature/bugfix branch.
- Commit and push until you are happy with your contribution.
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
- Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright
Copyright (c) 2014 Michaƫl Van Damme. See LICENSE.txt for further details.