ResqueDef
Forget resque boilerplate: focus on your code.
Install
In your Gemfile
add:
gem 'resque_def'
Then run $ bundle install
What
I love Resque, but I'm not in love with the amount of code needed to define and use a Resque task to do something like pull a user from a database, find open issues (assuming an issue model) and sending an email might look like this:
class User < ActiveRecord::Base
class DelaySendIssues
@queue = :delay_send_issues
def self.perform(id, state)
user = User.find(id)
issues = user.issues.where(state: state).all
UserMailer.send_issues(user: user, issues: issues).deliver
end
end
end
user = User.last
Resque.enqueue(User::SendDailyTriageEmail, user.id, 'open')
With ResqueDef, you can include a module, and define and use a Resque job like this:
class User < ActiveRecord::Base
include ResqueDef
resque_def(:delay_send_issues) do |id, state|
user = User.find(id)
issues = user.issues.where(state: state).all
UserMailer.send_issues(user: user, issues: issues).deliver
end
end
user = User.last
User.delay_send_issues(user.id, 'open')
So looking at the boiler plate (and none of the logic) we are reducing this:
class DelaySendIssues
@queue = :delay_send_issues
def self.perform(id, state)
end
end
To this:
resque_def(:delay_send_issues) do |id, state|
end
Pretty cool, huh? To do this, ResqueDef uses simple metaprogramming: Class.new
is used to define the require class, and then define_singleton_method
adds our method to the class included ResqueDef
. Not doing anything too magical. Check out the code for yourself!
Serializing Objects
By default Resque can only store JSON-able objects (strings, arrays, hashes, booleans). It cannot store active record objects.
TIL with Blocks
You can set default values in blocks like this:
resque_def(:foo) do |id, state = 'open', username = 'schneems'|
# ...
end
You can have an unlimited amount of args using a splat:
resque_def(:foo) do |id, *args|
# ...
end
License
MIT