perform_later 0.0.4 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/README.md +10 -26
- data/Rakefile +9 -1
- data/lib/object_perform_later.rb +2 -2
- data/lib/object_worker.rb +1 -2
- data/lib/perform_later.rb +24 -4
- data/lib/perform_later/args_parser.rb +49 -0
- data/lib/perform_later/config.rb +11 -0
- data/lib/perform_later/railtie.rb +5 -0
- data/lib/perform_later/version.rb +1 -1
- data/lib/perform_later/workers/active_record/lone_worker.rb +17 -0
- data/lib/perform_later/workers/active_record/worker.rb +15 -0
- data/lib/perform_later/workers/objects/lone_worker.rb +14 -0
- data/lib/perform_later/workers/objects/worker.rb +12 -0
- data/lib/resque/plugins/later/method.rb +34 -0
- data/perform_later.gemspec +7 -2
- data/spec/lib/object_perform_later_spec.rb +4 -9
- data/spec/lib/{resque_perform_later_spec.rb → perform_later/args_parser_spec.rb} +9 -8
- data/spec/lib/perform_later/config_spec.rb +11 -0
- data/spec/lib/perform_later_spec.rb +5 -0
- data/spec/lib/resque/plugins/later/method_spec.rb +53 -0
- data/spec/spec_helper.rb +9 -38
- data/spec/support/database_models.rb +8 -2
- metadata +131 -26
- data/lib/active_record_perform_later.rb +0 -24
- data/lib/active_record_worker.rb +0 -15
- data/lib/resque_perform_later.rb +0 -64
- data/spec/lib/active_record_perform_later_spec.rb +0 -30
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
![
|
2
|
-
|
3
|
-
[Image Credit](http://http://www.zazzle.com/anything_you_can_do_i_can_do_later_tshirt-235016986673229502)
|
1
|
+
[![Build Status](https://secure.travis-ci.org/KensoDev/perform_later.png)](https://secure.travis-ci.org/KensoDev/perform_later)
|
4
2
|
|
5
3
|
## Overview
|
6
4
|
Perform later is a gem meant to work with the [Resque](http://github.com/defunkt/resque) queue system.
|
7
5
|
|
8
|
-
The gem handles queuing tasks without the need to have additional "Worker" classes
|
6
|
+
The gem handles queuing tasks without the need to have additional "Worker" classes.
|
9
7
|
|
10
8
|
The gem will "translate" objects to a serializable (suitable for JSON) versions of those classes.
|
11
9
|
|
10
|
+
The Gem also support a workflow similar to `async_method`, meaning you can just call method on your objects and configure those methods to be queued by default. No worries, you can always call the method in `now` mode, which will execute the method in sync.
|
11
|
+
|
12
12
|
## Why?
|
13
13
|
*Why* should you queue something for later?
|
14
14
|
|
@@ -45,29 +45,17 @@ You can also call objects on the User object itself
|
|
45
45
|
User.perform_later(:queue_name, :method_name, args)
|
46
46
|
```
|
47
47
|
|
48
|
-
## Configuration
|
49
|
-
perform_later has a single configuration file, you should put the file in `config/resque_perform_later.yml`
|
50
|
-
|
51
|
-
```ruby
|
52
|
-
defaults: &DEFAULTS
|
53
|
-
enabled: true
|
54
48
|
|
55
|
-
development:
|
56
|
-
<<: *DEFAULTS
|
57
49
|
|
58
|
-
|
59
|
-
|
50
|
+
## Configuration
|
51
|
+
You can configure `perform_later` exactly as you configure your rails app.
|
60
52
|
|
61
|
-
|
62
|
-
<<: *DEFAULTS
|
53
|
+
Inside your `#{env}.rb` file (for example development.rb)
|
63
54
|
|
64
|
-
|
65
|
-
|
55
|
+
```ruby
|
56
|
+
config.perform_later.enabled = false # this will default to true if unset
|
66
57
|
```
|
67
58
|
|
68
|
-
### Configuration explained
|
69
|
-
The config is simple, either it's enabled or it's not, and you can set the environment which you want to enable in
|
70
|
-
|
71
59
|
## What happens in test when it's disabled
|
72
60
|
In test mode, the method is not queued, it's being sent immediately on the object, this way your test work completely normal and you don't need to worry about Resque or Redis in your tests, this is very useful
|
73
61
|
|
@@ -80,8 +68,4 @@ If you want to contribute (awesome), open a feature branch, base it on master.
|
|
80
68
|
Be as descriptive as you can in the pull request description, just to be clear what problem you are solving or what feature are you adding.
|
81
69
|
|
82
70
|
## TODO
|
83
|
-
1. Add the ability to perform_later without a queue provided (will go to a default queue - configurable)
|
84
|
-
2. Add generator for the configuration file
|
85
|
-
|
86
|
-
## Ideas
|
87
|
-
1. Add the ability that a method will be tagged as "perform_later", this way you can call the method by name and it will be queued
|
71
|
+
1. Add the ability to perform_later without a queue provided (will go to a default queue - configurable)
|
data/Rakefile
CHANGED
data/lib/object_perform_later.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module ObjectPerformLater
|
2
2
|
def perform_later(queue, method, *args)
|
3
|
-
if
|
4
|
-
args =
|
3
|
+
if PerformLater.config.enabled?
|
4
|
+
args = PerformLater::ArgsParser.args_to_resque(args)
|
5
5
|
Resque::Job.create(queue, ObjectWorker, self.name, method, *args)
|
6
6
|
else
|
7
7
|
self.send(method, *args)
|
data/lib/object_worker.rb
CHANGED
@@ -6,8 +6,7 @@ class ObjectWorker
|
|
6
6
|
# *args - array of arguments to send to the method
|
7
7
|
#
|
8
8
|
def self.perform(klass_name, method, *args)
|
9
|
-
args =
|
10
|
-
|
9
|
+
args = PerformLater::ArgsParser.args_from_resque(args)
|
11
10
|
klass_name.constantize.send(method, *args)
|
12
11
|
end
|
13
12
|
end
|
data/lib/perform_later.rb
CHANGED
@@ -1,12 +1,32 @@
|
|
1
|
+
require 'active_support/dependencies'
|
1
2
|
require 'perform_later/version'
|
3
|
+
require 'perform_later/config'
|
4
|
+
require 'resque'
|
5
|
+
require 'resque-loner'
|
6
|
+
require 'perform_later/args_parser'
|
2
7
|
require 'active_record'
|
3
|
-
require 'resque_perform_later'
|
4
8
|
require 'resque_mailer_patch'
|
5
9
|
require 'object_worker'
|
6
10
|
require 'object_perform_later'
|
7
|
-
require '
|
8
|
-
require '
|
11
|
+
require 'perform_later/workers/active_record/worker'
|
12
|
+
require 'perform_later/workers/active_record/lone_worker'
|
9
13
|
|
10
14
|
module PerformLater
|
11
|
-
|
15
|
+
def self.config
|
16
|
+
PerformLater::Config
|
17
|
+
end
|
12
18
|
end
|
19
|
+
|
20
|
+
module Resque
|
21
|
+
module Plugins
|
22
|
+
module Later
|
23
|
+
autoload :Method, 'resque/plugins/later/method'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
ActiveSupport.on_load(:active_record) do
|
29
|
+
include Resque::Plugins::Later::Method
|
30
|
+
end
|
31
|
+
|
32
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module PerformLater
|
2
|
+
class ArgsParser
|
3
|
+
APP_ROOT = File.expand_path((defined?(Rails) && Rails.root.to_s.length > 0) ? Rails.root : ".") unless defined?(APP_ROOT)
|
4
|
+
|
5
|
+
# inspired by DelayedJob
|
6
|
+
CLASS_STRING_FORMAT = /^CLASS\:([A-Z][\w\:]+)$/
|
7
|
+
AR_STRING_FORMAT = /^AR\:([A-Z][\w\:]+)\:(\d+)$/
|
8
|
+
YAML_STRING_FORMAT = /\A---/
|
9
|
+
|
10
|
+
def self.args_to_resque(*args)
|
11
|
+
args = args.map { |o|
|
12
|
+
case o
|
13
|
+
when ActiveRecord::Base
|
14
|
+
"AR:#{o.class.name}:#{o.id}"
|
15
|
+
when Class, Module
|
16
|
+
"CLASS:#{o.name}"
|
17
|
+
when Hash
|
18
|
+
o.to_yaml
|
19
|
+
else
|
20
|
+
o
|
21
|
+
end
|
22
|
+
} if args
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.args_from_resque(*args)
|
26
|
+
args = args.map { |o|
|
27
|
+
if o
|
28
|
+
case o
|
29
|
+
when CLASS_STRING_FORMAT then $1.constantize
|
30
|
+
when AR_STRING_FORMAT then $1.constantize.find_by_id($2)
|
31
|
+
when YAML_STRING_FORMAT then YAML.load(o)
|
32
|
+
else o
|
33
|
+
end
|
34
|
+
end
|
35
|
+
} if args
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def self.env_str
|
40
|
+
if defined? Rails
|
41
|
+
Rails.env.to_s
|
42
|
+
elsif defined? Rack
|
43
|
+
Rack.env.to_s
|
44
|
+
else
|
45
|
+
'production'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module PerformLater
|
2
|
+
module Workers
|
3
|
+
module ActiveRecord
|
4
|
+
class LoneWorker
|
5
|
+
include Resque::Plugins::UniqueJob
|
6
|
+
|
7
|
+
def self.perform(klass, id, method, *args)
|
8
|
+
args = PerformLater::ArgsParser.args_from_resque(args)
|
9
|
+
runner_klass = eval(klass)
|
10
|
+
|
11
|
+
record = runner_klass.where(:id => id).first
|
12
|
+
record.send(method, *args) if record
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module PerformLater
|
2
|
+
module Workers
|
3
|
+
module ActiveRecord
|
4
|
+
class Worker
|
5
|
+
def self.perform(klass, id, method, *args)
|
6
|
+
args = PerformLater::ArgsParser.args_from_resque(args)
|
7
|
+
runner_klass = eval(klass)
|
8
|
+
|
9
|
+
record = runner_klass.where(:id => id).first
|
10
|
+
record.send(method, *args) if record
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module PerformLater
|
2
|
+
module Workers
|
3
|
+
module Objects
|
4
|
+
class LoneWorker
|
5
|
+
include Resque::Plugins::UniqueJob
|
6
|
+
|
7
|
+
def self.perform(klass_name, method, *args)
|
8
|
+
args = PerformLater::ArgsParser.args_from_resque(args)
|
9
|
+
klass_name.constantize.send(method, *args)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Resque::Plugins::Later::Method
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
def later(method_name, opts={})
|
6
|
+
alias_method "now_#{method_name}", method_name
|
7
|
+
return unless PerformLater.config.enabled?
|
8
|
+
|
9
|
+
define_method "#{method_name}" do |*args|
|
10
|
+
loner = opts.fetch(:loner, false)
|
11
|
+
queue = opts.fetch(:queue, :generic)
|
12
|
+
klass = PerformLater::Workers::ActiveRecord::Worker
|
13
|
+
klass = PerformLater::Workers::ActiveRecord::LoneWorker if loner
|
14
|
+
|
15
|
+
if loner
|
16
|
+
return "QUEUED!" if Resque.enqueued_in? queue, klass, args
|
17
|
+
end
|
18
|
+
|
19
|
+
Resque::Job.create(queue, klass, send(:class).name, send(:id), "now_#{method_name}", args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def perform_later(queue, method, *args)
|
25
|
+
ActiveSupport::Deprecation.warn("perform_later will be deprecated in future versions, please use the later method on your models")
|
26
|
+
|
27
|
+
if PerformLater.config.enabled?
|
28
|
+
args = PerformLater::ArgsParser.args_to_resque(args)
|
29
|
+
Resque::Job.create(queue, PerformLater::Workers::ActiveRecord::Worker, self.class.name, self.id, method, *args)
|
30
|
+
else
|
31
|
+
self.send(method, *args)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/perform_later.gemspec
CHANGED
@@ -19,11 +19,16 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
# specify any dependencies here; for example:
|
22
|
-
s.add_dependency '
|
23
|
-
s.add_dependency 'redis'
|
22
|
+
s.add_dependency 'rails', '~> 3.0'
|
24
23
|
s.add_dependency 'resque'
|
24
|
+
s.add_dependency 'resque-loner'
|
25
|
+
s.add_dependency 'redis'
|
26
|
+
|
25
27
|
|
26
28
|
s.add_development_dependency 'rake'
|
29
|
+
s.add_development_dependency 'rspec-rails'
|
27
30
|
s.add_development_dependency 'rspec'
|
28
31
|
s.add_development_dependency 'sqlite3'
|
32
|
+
s.add_development_dependency 'spork-rails'
|
33
|
+
s.add_development_dependency 'fakeredis'
|
29
34
|
end
|
@@ -1,26 +1,21 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ObjectPerformLater do
|
4
|
-
let(:enabled) do
|
5
|
-
{ 'enabled' => true }
|
6
|
-
end
|
7
|
-
let(:disabled) do
|
8
|
-
{ 'enabled' => false }
|
9
|
-
end
|
10
|
-
|
11
4
|
it "should insert a task into resque when the config is enabled" do
|
12
5
|
Resque.redis = $redis
|
13
6
|
|
14
|
-
|
7
|
+
PerformLater.config.stub!(:enabled?).and_return(true)
|
15
8
|
User.perform_later(:generic, :get_metadata)
|
16
9
|
|
17
10
|
Resque.peek(:generic, 0, 20).length.should == 1
|
18
11
|
end
|
19
12
|
|
20
13
|
it "should send the method on the class when the config is disabled" do
|
21
|
-
|
14
|
+
PerformLater.config.stub!(:enabled?).and_return(false)
|
22
15
|
|
23
16
|
User.should_receive(:get_metadata)
|
24
17
|
User.perform_later(:generic, :get_metadata)
|
18
|
+
|
19
|
+
Resque.peek(:generic, 0, 20).length.should == 0
|
25
20
|
end
|
26
21
|
end
|
@@ -1,24 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe PerformLater::ArgsParser do
|
4
|
+
subject { PerformLater::ArgsParser }
|
4
5
|
let(:user) { User.create }
|
5
6
|
|
6
7
|
context "args to resque" do
|
7
8
|
it "should convert the AR object to the proper string" do
|
8
9
|
user_id = user.id
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
subject.args_to_resque(user).length.should == 1
|
12
|
+
subject.args_to_resque(user)[0].should == "AR:User:#{user_id}"
|
12
13
|
end
|
13
14
|
|
14
15
|
it "should convert a hash into YAML string so that Resque will be able to JSON convert it" do
|
15
16
|
hash = {name: "something", other: "something else"}
|
16
|
-
|
17
|
+
subject.args_to_resque(hash)[0].class.name.should == "String"
|
17
18
|
end
|
18
19
|
|
19
20
|
it "should be able to load a yaml from the string and translate it into the same hash again" do
|
20
21
|
hash = {name: "something", other: "something else"}
|
21
|
-
yaml =
|
22
|
+
yaml = subject.args_to_resque(hash)[0]
|
22
23
|
|
23
24
|
loaded_yaml = YAML.load(yaml)
|
24
25
|
|
@@ -28,7 +29,7 @@ describe ResquePerformLater do
|
|
28
29
|
|
29
30
|
it "should convert a class to the proper string representation" do
|
30
31
|
klass = User
|
31
|
-
|
32
|
+
subject.args_to_resque(klass)[0].should == "CLASS:User"
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
@@ -37,14 +38,14 @@ describe ResquePerformLater do
|
|
37
38
|
hash = {name: "something", other: "something else"}
|
38
39
|
yaml = hash.to_yaml
|
39
40
|
|
40
|
-
args =
|
41
|
+
args = subject.args_from_resque(yaml)
|
41
42
|
args[0].class.name.should == "Hash"
|
42
43
|
args[0][:name].should == "something"
|
43
44
|
args[0][:other].should == "something else"
|
44
45
|
end
|
45
46
|
|
46
47
|
it "Should give me a user model back when I pass the proper string" do
|
47
|
-
args =
|
48
|
+
args = subject.args_from_resque("AR:User:#{user.id}")
|
48
49
|
args[0].should == user
|
49
50
|
end
|
50
51
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'perform_later/config'
|
2
|
+
|
3
|
+
describe PerformLater::Config do
|
4
|
+
before(:each) { PerformLater.config.enabled = false }
|
5
|
+
|
6
|
+
it "should set the perform later mode" do
|
7
|
+
PerformLater.config.enabled?.should be_false
|
8
|
+
PerformLater.config.enabled = true
|
9
|
+
PerformLater.config.enabled?.should == true
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'perform_later'
|
3
|
+
|
4
|
+
describe Resque::Plugins::Later::Method do
|
5
|
+
before(:each) { PerformLater.config.enabled = true }
|
6
|
+
before(:each) { Resque.redis = $redis }
|
7
|
+
|
8
|
+
context "enabled" do
|
9
|
+
before(:each) do
|
10
|
+
PerformLater.config.stub!(:enabled?).and_return(true)
|
11
|
+
User.later :long_running_method
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should insert a task into resque when the config is enabled" do
|
15
|
+
user = User.create
|
16
|
+
user.long_running_method
|
17
|
+
Resque.peek(:generic, 0, 20).length.should == 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "loner" do
|
22
|
+
before(:each) do
|
23
|
+
PerformLater.config.stub!(:enabled?).and_return(true)
|
24
|
+
User.later :lonely_long_running_method, loner: true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should only add a single method to the queue, since the config is with a loner" do
|
28
|
+
user = User.create
|
29
|
+
user.lonely_long_running_method
|
30
|
+
user.lonely_long_running_method
|
31
|
+
user.lonely_long_running_method
|
32
|
+
user.lonely_long_running_method
|
33
|
+
user.lonely_long_running_method
|
34
|
+
Resque.peek(:generic, 0, 20).length.should == 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "disabled" do
|
39
|
+
it "should send the method on the class when the config is disabled" do
|
40
|
+
user = User.create
|
41
|
+
user.now_long_running_method
|
42
|
+
Resque.peek(:generic, 0, 20).length.should == 0
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "shold define the correct method on the user model" do
|
47
|
+
user = User.create
|
48
|
+
user.should respond_to(:long_running_method)
|
49
|
+
user.should respond_to(:now_long_running_method)
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "uri"
|
1
3
|
require "perform_later"
|
2
4
|
require "rspec"
|
3
5
|
require "support/database_connection"
|
4
6
|
require "support/database_models"
|
5
7
|
require "redis"
|
8
|
+
require 'fakeredis/rspec'
|
9
|
+
|
10
|
+
|
6
11
|
|
7
12
|
RSpec.configure do |config|
|
8
13
|
config.mock_with :rspec
|
9
14
|
|
10
|
-
config.after(:each) do
|
11
|
-
$redis.flushdb
|
12
|
-
end
|
13
|
-
|
14
15
|
config.before(:all) do
|
15
16
|
dir = File.join(File.dirname(__FILE__), 'support/db')
|
16
17
|
|
@@ -19,41 +20,11 @@ RSpec.configure do |config|
|
|
19
20
|
FileUtils.cp(File.join(dir, '.blank.sqlite3'), File.join(dir, 'test.sqlite3'))
|
20
21
|
end
|
21
22
|
|
22
|
-
root = File.dirname(__FILE__)
|
23
|
-
REDIS_PID = File.join(root, "tmp/pids/redis-test.pid")
|
24
|
-
REDIS_CACHE_PATH = File.join(root, "tmp/cache/")
|
25
|
-
|
26
|
-
FileUtils.mkdir_p File.join(root, "tmp/pids")
|
27
|
-
FileUtils.mkdir_p File.join(root, "tmp/cache")
|
28
|
-
|
29
23
|
config.before(:suite) do
|
30
|
-
|
31
|
-
"daemonize" => 'yes',
|
32
|
-
"pidfile" => REDIS_PID,
|
33
|
-
"port" => 9726,
|
34
|
-
"timeout" => 300,
|
35
|
-
"save 900" => 1,
|
36
|
-
"save 300" => 1,
|
37
|
-
"save 60" => 10000,
|
38
|
-
"dbfilename" => "dump.rdb",
|
39
|
-
"dir" => REDIS_CACHE_PATH,
|
40
|
-
"loglevel" => "debug",
|
41
|
-
"logfile" => "stdout",
|
42
|
-
"databases" => 16
|
43
|
-
}.map { |k, v| "#{k} #{v}" }.join('\n')
|
44
|
-
cmd = "echo '#{redis_options}' | redis-server -"
|
45
|
-
system cmd
|
46
|
-
|
47
|
-
|
48
|
-
uri = URI.parse("http://localhost:9726")
|
49
|
-
$redis = Redis.new(host: uri.host, port: uri.port)
|
24
|
+
$redis = Redis.new
|
50
25
|
end
|
51
|
-
|
52
|
-
config.after(:
|
53
|
-
|
54
|
-
cat #{REDIS_PID} | xargs kill -QUIT
|
55
|
-
rm -f #{REDIS_CACHE_PATH}dump.rdb
|
56
|
-
rm -f #{REDIS_PID}
|
57
|
-
}
|
26
|
+
|
27
|
+
config.after(:each) do
|
28
|
+
$redis.flushdb
|
58
29
|
end
|
59
30
|
end
|
@@ -1,7 +1,13 @@
|
|
1
1
|
class User < ActiveRecord::Base
|
2
|
-
def
|
3
|
-
|
2
|
+
def long_running_method
|
3
|
+
true
|
4
4
|
end
|
5
|
+
later :long_running_method
|
6
|
+
|
7
|
+
def lonely_long_running_method
|
8
|
+
true
|
9
|
+
end
|
10
|
+
later :lonely_long_running_method, :loner => true
|
5
11
|
|
6
12
|
def self.get_metadata
|
7
13
|
{}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perform_later
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: '1.0'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,43 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement:
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: resque
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
17
33
|
none: false
|
18
34
|
requirements:
|
19
35
|
- - ! '>='
|
20
36
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
37
|
+
version: '0'
|
22
38
|
type: :runtime
|
23
39
|
prerelease: false
|
24
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
25
46
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
27
|
-
requirement:
|
47
|
+
name: resque-loner
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
28
49
|
none: false
|
29
50
|
requirements:
|
30
51
|
- - ! '>='
|
@@ -32,10 +53,15 @@ dependencies:
|
|
32
53
|
version: '0'
|
33
54
|
type: :runtime
|
34
55
|
prerelease: false
|
35
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
36
62
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement:
|
63
|
+
name: redis
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
39
65
|
none: false
|
40
66
|
requirements:
|
41
67
|
- - ! '>='
|
@@ -43,10 +69,15 @@ dependencies:
|
|
43
69
|
version: '0'
|
44
70
|
type: :runtime
|
45
71
|
prerelease: false
|
46
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
47
78
|
- !ruby/object:Gem::Dependency
|
48
79
|
name: rake
|
49
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
50
81
|
none: false
|
51
82
|
requirements:
|
52
83
|
- - ! '>='
|
@@ -54,10 +85,31 @@ dependencies:
|
|
54
85
|
version: '0'
|
55
86
|
type: :development
|
56
87
|
prerelease: false
|
57
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rspec-rails
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
58
110
|
- !ruby/object:Gem::Dependency
|
59
111
|
name: rspec
|
60
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
61
113
|
none: false
|
62
114
|
requirements:
|
63
115
|
- - ! '>='
|
@@ -65,10 +117,15 @@ dependencies:
|
|
65
117
|
version: '0'
|
66
118
|
type: :development
|
67
119
|
prerelease: false
|
68
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
69
126
|
- !ruby/object:Gem::Dependency
|
70
127
|
name: sqlite3
|
71
|
-
requirement:
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
72
129
|
none: false
|
73
130
|
requirements:
|
74
131
|
- - ! '>='
|
@@ -76,7 +133,44 @@ dependencies:
|
|
76
133
|
version: '0'
|
77
134
|
type: :development
|
78
135
|
prerelease: false
|
79
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: spork-rails
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: fakeredis
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
80
174
|
description: Queue any method in any class or instance with no need for additional
|
81
175
|
Worker class and no extra code
|
82
176
|
email:
|
@@ -86,23 +180,32 @@ extensions: []
|
|
86
180
|
extra_rdoc_files: []
|
87
181
|
files:
|
88
182
|
- .gitignore
|
183
|
+
- .rspec
|
184
|
+
- .travis.yml
|
89
185
|
- Gemfile
|
90
186
|
- README.md
|
91
187
|
- Rakefile
|
92
188
|
- init.rb
|
93
|
-
- lib/active_record_perform_later.rb
|
94
|
-
- lib/active_record_worker.rb
|
95
189
|
- lib/object_perform_later.rb
|
96
190
|
- lib/object_worker.rb
|
97
191
|
- lib/perform_later.rb
|
192
|
+
- lib/perform_later/args_parser.rb
|
193
|
+
- lib/perform_later/config.rb
|
194
|
+
- lib/perform_later/railtie.rb
|
98
195
|
- lib/perform_later/version.rb
|
196
|
+
- lib/perform_later/workers/active_record/lone_worker.rb
|
197
|
+
- lib/perform_later/workers/active_record/worker.rb
|
198
|
+
- lib/perform_later/workers/objects/lone_worker.rb
|
199
|
+
- lib/perform_later/workers/objects/worker.rb
|
200
|
+
- lib/resque/plugins/later/method.rb
|
99
201
|
- lib/resque_mailer_patch.rb
|
100
|
-
- lib/resque_perform_later.rb
|
101
202
|
- license
|
102
203
|
- perform_later.gemspec
|
103
|
-
- spec/lib/active_record_perform_later_spec.rb
|
104
204
|
- spec/lib/object_perform_later_spec.rb
|
105
|
-
- spec/lib/
|
205
|
+
- spec/lib/perform_later/args_parser_spec.rb
|
206
|
+
- spec/lib/perform_later/config_spec.rb
|
207
|
+
- spec/lib/perform_later_spec.rb
|
208
|
+
- spec/lib/resque/plugins/later/method_spec.rb
|
106
209
|
- spec/spec_helper.rb
|
107
210
|
- spec/support/database_connection.rb
|
108
211
|
- spec/support/database_models.rb
|
@@ -128,15 +231,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
231
|
version: '0'
|
129
232
|
requirements: []
|
130
233
|
rubyforge_project: perform_later
|
131
|
-
rubygems_version: 1.8.
|
234
|
+
rubygems_version: 1.8.24
|
132
235
|
signing_key:
|
133
236
|
specification_version: 3
|
134
237
|
summary: Queue any method in any class or instance with no need for additional Worker
|
135
238
|
class and no extra code
|
136
239
|
test_files:
|
137
|
-
- spec/lib/active_record_perform_later_spec.rb
|
138
240
|
- spec/lib/object_perform_later_spec.rb
|
139
|
-
- spec/lib/
|
241
|
+
- spec/lib/perform_later/args_parser_spec.rb
|
242
|
+
- spec/lib/perform_later/config_spec.rb
|
243
|
+
- spec/lib/perform_later_spec.rb
|
244
|
+
- spec/lib/resque/plugins/later/method_spec.rb
|
140
245
|
- spec/spec_helper.rb
|
141
246
|
- spec/support/database_connection.rb
|
142
247
|
- spec/support/database_models.rb
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module ActiveRecordPerformLater
|
2
|
-
module InstanceMethods
|
3
|
-
def perform_later(queue, method, *args)
|
4
|
-
if ResquePerformLater.config['enabled']
|
5
|
-
args = ResquePerformLater.args_to_resque(args)
|
6
|
-
|
7
|
-
Resque::Job.create(queue,
|
8
|
-
ActiveRecordWorker,
|
9
|
-
self.class.name,
|
10
|
-
self.id,
|
11
|
-
method,
|
12
|
-
*args)
|
13
|
-
else
|
14
|
-
self.send(method, *args)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.included(receiver)
|
20
|
-
receiver.send :include, InstanceMethods
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
ActiveRecord::Base.send :include, ActiveRecordPerformLater
|
data/lib/active_record_worker.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
class ActiveRecordWorker
|
2
|
-
# Public: perform.
|
3
|
-
#
|
4
|
-
# klass_name - name of the class (string).
|
5
|
-
# method - method name, this method will be called on the object.
|
6
|
-
# *args - array of arguments to send to the method
|
7
|
-
#
|
8
|
-
def self.perform(klass, id, method, *args)
|
9
|
-
args = ResquePerformLater.args_from_resque(args)
|
10
|
-
runner_klass = eval(klass)
|
11
|
-
|
12
|
-
record = runner_klass.where(:id => id).first
|
13
|
-
record.send(method, *args) if record
|
14
|
-
end
|
15
|
-
end
|
data/lib/resque_perform_later.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
class ResquePerformLater
|
2
|
-
APP_ROOT = File.expand_path((defined?(Rails) && Rails.root.to_s.length > 0) ? Rails.root : ".") unless defined?(APP_ROOT)
|
3
|
-
DEFAULT_CONFIG_PATH = File.join(APP_ROOT, 'config', 'resque_perform_later.yml')
|
4
|
-
DEFAULT_CONFIG = {
|
5
|
-
'enabled' => true
|
6
|
-
}
|
7
|
-
|
8
|
-
# inspired by DelayedJob
|
9
|
-
CLASS_STRING_FORMAT = /^CLASS\:([A-Z][\w\:]+)$/
|
10
|
-
AR_STRING_FORMAT = /^AR\:([A-Z][\w\:]+)\:(\d+)$/
|
11
|
-
YAML_STRING_FORMAT = /\A---/
|
12
|
-
|
13
|
-
def self.args_to_resque(*args)
|
14
|
-
args = args.map { |o|
|
15
|
-
case o
|
16
|
-
when ActiveRecord::Base
|
17
|
-
"AR:#{o.class.name}:#{o.id}"
|
18
|
-
when Class, Module
|
19
|
-
"CLASS:#{o.name}"
|
20
|
-
when Hash
|
21
|
-
o.to_yaml
|
22
|
-
else
|
23
|
-
o
|
24
|
-
end
|
25
|
-
} if args
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.args_from_resque(*args)
|
29
|
-
args = args.map { |o|
|
30
|
-
if o
|
31
|
-
case o
|
32
|
-
when CLASS_STRING_FORMAT then $1.constantize
|
33
|
-
when AR_STRING_FORMAT then $1.constantize.find_by_id($2)
|
34
|
-
when YAML_STRING_FORMAT then YAML.load(o)
|
35
|
-
else o
|
36
|
-
end
|
37
|
-
end
|
38
|
-
} if args
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
def self.env_str
|
43
|
-
if defined? Rails
|
44
|
-
Rails.env.to_s
|
45
|
-
elsif defined? Rack
|
46
|
-
Rack.env.to_s
|
47
|
-
else
|
48
|
-
'production'
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
@@_config = nil
|
53
|
-
|
54
|
-
def self.config
|
55
|
-
return @@_config if @@_config && self.env_str != 'development'
|
56
|
-
|
57
|
-
if File.exists?(DEFAULT_CONFIG_PATH)
|
58
|
-
config = YAML.load(ERB.new(IO.read(DEFAULT_CONFIG_PATH)).result)[self.env_str]
|
59
|
-
end
|
60
|
-
|
61
|
-
config = {}.merge(DEFAULT_CONFIG || {}).merge(config || {})
|
62
|
-
@@_config = config
|
63
|
-
end
|
64
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'resque'
|
3
|
-
|
4
|
-
describe ActiveRecordPerformLater do
|
5
|
-
let(:user) { User.create }
|
6
|
-
|
7
|
-
let(:enabled) do
|
8
|
-
{ 'enabled' => true }
|
9
|
-
end
|
10
|
-
let(:disabled) do
|
11
|
-
{ 'enabled' => false }
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should insert a task into resque when the config is enabled" do
|
15
|
-
Resque.redis = $redis
|
16
|
-
|
17
|
-
ResquePerformLater.stub!(:config).and_return(enabled)
|
18
|
-
user.perform_later(:generic, :full_name)
|
19
|
-
|
20
|
-
Resque.peek(:generic, 0, 20).length.should == 1
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should send the method on the class when the config is disabled" do
|
24
|
-
ResquePerformLater.stub!(:config).and_return(disabled)
|
25
|
-
user.should_receive(:full_name)
|
26
|
-
user.perform_later(:generic, :full_name)
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
end
|