Skip to content
This repository was archived by the owner on Sep 22, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
resque-async-method (1.0.1)
resque-async-method (1.1)
activesupport
resque

Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ Usage
# do stuff
end
async_method :send_a_very_long_email, queue: 'emails'

# And for class methods
def User.send_all_emails
# do stuff
end

async_class_method :send_all_emails, queue: "emails"
end

u = User.find(1)
Expand Down
1 change: 1 addition & 0 deletions lib/resque-async-method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Plugins
module Async
autoload :Method, 'resque/plugins/async/method'
autoload :Worker, 'resque/plugins/async/worker'
autoload :ClassWorker, 'resque/plugins/async/class_worker'
end
end
end
Expand Down
22 changes: 22 additions & 0 deletions lib/resque/plugins/async/class_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Resque::Plugins::Async::ClassWorker
@queue = :async_class_methods

def self.queue=(name)
@queue = name
end

def self.queue
@queue
end

def self.perform(klass, *args)
arguments = args.map { |arg|
if arg.is_a?(Hash) && arg.has_key?("_obj_class_name") && arg.has_key?("_obj_id")
arg["_obj_class_name"].constantize.find(arg["_obj_id"])
else
arg
end
}
klass.constantize.send(arguments.shift, *arguments)
end
end
43 changes: 43 additions & 0 deletions lib/resque/plugins/async/method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,41 @@ module Resque::Plugins::Async::Method
class NotPersistedError < StandardError; end

module ClassMethods

def async_class_method(method_name, opts={})
# Allow tests to call sync_ methods ...

eval(%Q{
class << self
alias_method :sync_#{method_name}, :#{method_name}
end})

# ... but don't actually make them asynchronous
# return if Rails.env.test?
define_singleton_method "#{method_name}" do |*args|

my_klass = Resque::Plugins::Async::ClassWorker
my_klass.queue = opts[:queue] ||
send(:class).name.underscore.pluralize

# Convert AR::Base params to hash directive, restored in Worker and ClassWorker
*args = *args.map do |arg|
if arg.kind_of?(ActiveRecord::Base)
{"_obj_class_name" => arg.class.name, "_obj_id" => arg.id}
else
arg
end
end

Resque.enqueue(
my_klass,
self.name,
:"sync_#{method_name}",
*args
)
end
end

def async_method(method_name, opts={})
# Allow tests to call sync_ methods ...
alias_method :"sync_#{method_name}", method_name
Expand All @@ -20,6 +55,14 @@ def async_method(method_name, opts={})
my_klass.queue = opts[:queue] ||
send(:class).name.underscore.pluralize

*args = *args.map do |arg|
if arg.kind_of?(ActiveRecord::Base)
{"_obj_class_name" => arg.class.name, "_obj_id" => arg.id}
else
arg
end
end

Resque.enqueue(
my_klass,
send(:class).name,
Expand Down
9 changes: 8 additions & 1 deletion lib/resque/plugins/async/worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ def self.queue
end

def self.perform(klass, *args)
klass.constantize.find(args.shift).send(args.shift, *args)
arguments = args.map { |arg|
if arg.is_a?(Hash) && arg.has_key?("_obj_class_name") && arg.has_key?("_obj_id")
arg["_obj_class_name"].constantize.find(arg["_obj_id"])
else
arg
end
}
klass.constantize.find(arguments.shift).send(arguments.shift, *arguments)
end
end
18 changes: 18 additions & 0 deletions test/async_method_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ class AsyncMethodTest < ActiveSupport::TestCase
assert_equal 'success!', user.sync_long_method
end

test "enqueue class jobs" do
assert_equal true, User.class_method_is_awesome
assert_equal "success!", User.sync_class_method_is_awesome
end

test "enqueue class jobs with params" do
assert_equal true, User.class_methods_with_awesome_vars(1,2)
assert_equal 3, User.sync_class_methods_with_awesome_vars(1,2)
end

test "enqueue method with object parameters" do
user1 = User.first
user2 = User.last

assert_equal true, user1.kiss(user2)
assert_equal "#{user1.name} kissed #{user2.name}", user1.sync_kiss(user2)
end

test "raise error if not persisted" do
user = User.new

Expand Down
20 changes: 20 additions & 0 deletions test/dummy/app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
class User < ActiveRecord::Base

def User.class_method_is_awesome
return "success!"
end

async_class_method :class_method_is_awesome

def User.class_methods_with_awesome_vars(num1, num2)
return num1.to_i + num2.to_i
end

async_class_method :class_methods_with_awesome_vars

def long_method
sleep 2

return "success!"
end

async_method :long_method, queue: 'long-methods'

def another_long_method
Expand All @@ -12,4 +26,10 @@ def another_long_method
return "success!"
end
async_method :another_long_method

def kiss(other_user)
return "#{self.name} kissed #{other_user.name}"
end

async_method :kiss
end
Binary file modified test/dummy/db/test.sqlite3
Binary file not shown.
Loading