perform_later 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +29 -1
- data/lib/perform_later.rb +2 -0
- data/lib/perform_later/args_parser.rb +16 -5
- data/lib/perform_later/plugins.rb +17 -0
- data/lib/perform_later/version.rb +1 -1
- data/lib/perform_later/workers/active_record/lone_worker.rb +5 -9
- data/lib/perform_later/workers/active_record/worker.rb +4 -8
- data/lib/perform_later/workers/base.rb +19 -0
- data/lib/perform_later/workers/objects/lone_worker.rb +3 -8
- data/lib/perform_later/workers/objects/worker.rb +2 -10
- data/spec/lib/perform_later/args_parser_spec.rb +17 -0
- data/spec/lib/perform_later/plugins_spec.rb +33 -0
- data/spec/lib/perform_later/workers/objects/worker_spec.rb +9 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/db/test.sqlite3 +0 -0
- metadata +6 -2
data/README.md
CHANGED
@@ -33,7 +33,7 @@ In an initializer, all you need to say is whether you want perform later to be e
|
|
33
33
|
|
34
34
|
```ruby
|
35
35
|
unless Rails.env.test?
|
36
|
-
PerformLater.config.
|
36
|
+
PerformLater.config.enabled = true # this will default to false if unset
|
37
37
|
end
|
38
38
|
```
|
39
39
|
|
@@ -130,6 +130,34 @@ Basically, the `ArgsParser` class allows you to keep passing any args you want t
|
|
130
130
|
|
131
131
|
`ArgsParser` also patched `resque-mailer` so you can pass in AR objects to mailers as well.
|
132
132
|
|
133
|
+
## The custom finder
|
134
|
+
I found the need to add a custom finder to the args parser.
|
135
|
+
|
136
|
+
### Why?
|
137
|
+
At Gogobot for example, we use slave databases, those sometimes have lag, so when the finder is executed it returns nil, even though the record is actually on the master.
|
138
|
+
|
139
|
+
So, I added support for custom finders.
|
140
|
+
|
141
|
+
#### Example:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
class CustomFinder
|
145
|
+
def self.find(klass, id)
|
146
|
+
Octopus.using(:master) {
|
147
|
+
klass.where(id: id).first
|
148
|
+
} unless klass.where(id: id).first
|
149
|
+
end
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
153
|
+
Then in an initializer
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
PerformLater::Plugins.add_finder(CustomFinder)
|
157
|
+
```
|
158
|
+
|
159
|
+
So, at Gogobot for example, we will fall back to master if the record was not found on the slave DB.
|
160
|
+
|
133
161
|
|
134
162
|
## Contribute / Bug reports
|
135
163
|
|
data/lib/perform_later.rb
CHANGED
@@ -3,10 +3,12 @@ require 'perform_later/version'
|
|
3
3
|
require 'perform_later/config'
|
4
4
|
require 'perform_later/payload_helper'
|
5
5
|
require 'perform_later/args_parser'
|
6
|
+
require 'perform_later/plugins'
|
6
7
|
require 'resque'
|
7
8
|
require 'active_record'
|
8
9
|
require 'resque_mailer_patch'
|
9
10
|
require 'object_perform_later'
|
11
|
+
require 'perform_later/workers/base'
|
10
12
|
require 'perform_later/workers/active_record/worker'
|
11
13
|
require 'perform_later/workers/active_record/lone_worker'
|
12
14
|
require 'perform_later/workers/objects/worker'
|
@@ -18,13 +18,24 @@ module PerformLater
|
|
18
18
|
if o
|
19
19
|
o = args_from_resque(o) if o.is_a?(Array)
|
20
20
|
case o
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
when CLASS_STRING_FORMAT
|
22
|
+
$1.constantize
|
23
|
+
when AR_STRING_FORMAT
|
24
|
+
runner_class = $1.constantize
|
25
|
+
id = $2
|
26
|
+
|
27
|
+
if PerformLater::Plugins.finder_class
|
28
|
+
PerformLater::Plugins.finder_class.find(runner_class, id)
|
29
|
+
else
|
30
|
+
runner_class.where(id: id).first
|
31
|
+
end
|
32
|
+
when YAML_STRING_FORMAT
|
33
|
+
YAML.load(o)
|
34
|
+
else
|
35
|
+
o
|
25
36
|
end
|
26
37
|
end
|
27
|
-
} if args
|
38
|
+
} if args
|
28
39
|
end
|
29
40
|
|
30
41
|
private
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module PerformLater
|
2
|
+
class Plugins
|
3
|
+
def self.finder_class
|
4
|
+
@@finder_class ||= nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.add_finder(klass)
|
8
|
+
if klass.respond_to?(:find)
|
9
|
+
@@finder_class = klass
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.clear_finder!
|
14
|
+
@@finder_class = nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,22 +1,18 @@
|
|
1
1
|
module PerformLater
|
2
2
|
module Workers
|
3
3
|
module ActiveRecord
|
4
|
-
class LoneWorker
|
4
|
+
class LoneWorker < PerformLater::Workers::Base
|
5
5
|
def self.perform(klass, id, method, *args)
|
6
6
|
# Remove the loner flag from redis
|
7
7
|
digest = PerformLater::PayloadHelper.get_digest(klass, method, args)
|
8
8
|
Resque.redis.del(digest)
|
9
9
|
|
10
10
|
args = PerformLater::ArgsParser.args_from_resque(args)
|
11
|
-
runner_klass =
|
11
|
+
runner_klass = klass.constantize
|
12
12
|
|
13
|
-
record = runner_klass.
|
14
|
-
|
15
|
-
|
16
|
-
record.send(method, *args) if record
|
17
|
-
else
|
18
|
-
record.send(method) if record
|
19
|
-
end
|
13
|
+
record = runner_klass.find(id)
|
14
|
+
|
15
|
+
perform_job(record, method, args)
|
20
16
|
end
|
21
17
|
end
|
22
18
|
end
|
@@ -1,18 +1,14 @@
|
|
1
1
|
module PerformLater
|
2
2
|
module Workers
|
3
3
|
module ActiveRecord
|
4
|
-
class Worker
|
4
|
+
class Worker < PerformLater::Workers::Base
|
5
5
|
def self.perform(klass, id, method, *args)
|
6
6
|
args = PerformLater::ArgsParser.args_from_resque(args)
|
7
|
-
runner_klass =
|
7
|
+
runner_klass = klass.constantize
|
8
8
|
|
9
|
-
record = runner_klass.
|
9
|
+
record = runner_klass.find(id)
|
10
10
|
|
11
|
-
|
12
|
-
record.send(method, *args) if record
|
13
|
-
else
|
14
|
-
record.send(method) if record
|
15
|
-
end
|
11
|
+
perform_job(record, method, args)
|
16
12
|
end
|
17
13
|
end
|
18
14
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module PerformLater
|
2
|
+
module Workers
|
3
|
+
class Base
|
4
|
+
|
5
|
+
protected
|
6
|
+
def self.perform_job(object, method, arguments)
|
7
|
+
unless arguments.empty?
|
8
|
+
if arguments.size == 1
|
9
|
+
object.send(method, arguments.first)
|
10
|
+
else
|
11
|
+
object.send(method, *arguments)
|
12
|
+
end
|
13
|
+
else
|
14
|
+
object.send(method)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,19 +1,14 @@
|
|
1
1
|
module PerformLater
|
2
2
|
module Workers
|
3
3
|
module Objects
|
4
|
-
class LoneWorker
|
4
|
+
class LoneWorker < PerformLater::Workers::Base
|
5
5
|
def self.perform(klass_name, method, *args)
|
6
|
-
#
|
7
6
|
digest = PerformLater::PayloadHelper.get_digest(klass_name, method, args)
|
8
7
|
Resque.redis.del(digest)
|
9
8
|
|
10
|
-
|
9
|
+
arguments = PerformLater::ArgsParser.args_from_resque(args)
|
11
10
|
|
12
|
-
|
13
|
-
klass_name.constantize.send(method, *args)
|
14
|
-
else
|
15
|
-
klass_name.constantize.send(method)
|
16
|
-
end
|
11
|
+
perform_job(klass_name.constantize, method, arguments)
|
17
12
|
end
|
18
13
|
end
|
19
14
|
end
|
@@ -1,19 +1,11 @@
|
|
1
1
|
module PerformLater
|
2
2
|
module Workers
|
3
3
|
module Objects
|
4
|
-
class Worker
|
4
|
+
class Worker < PerformLater::Workers::Base
|
5
5
|
def self.perform(klass_name, method, *args)
|
6
6
|
arguments = PerformLater::ArgsParser.args_from_resque(args)
|
7
7
|
|
8
|
-
|
9
|
-
if arguments.size == 1
|
10
|
-
klass_name.constantize.send(method, arguments.first)
|
11
|
-
else
|
12
|
-
klass_name.constantize.send(method, *arguments)
|
13
|
-
end
|
14
|
-
else
|
15
|
-
klass_name.constantize.send(method)
|
16
|
-
end
|
8
|
+
perform_job(klass_name.constantize, method, arguments)
|
17
9
|
end
|
18
10
|
end
|
19
11
|
end
|
@@ -1,9 +1,26 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
class CustomFinder
|
4
|
+
def self.find(klass, id)
|
5
|
+
klass.find(id)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
describe PerformLater::ArgsParser do
|
4
10
|
subject { PerformLater::ArgsParser }
|
5
11
|
let(:user) { User.create }
|
6
12
|
|
13
|
+
context "Custom finder" do
|
14
|
+
it "should invoke the custom class finder method" do
|
15
|
+
CustomFinder.should_receive(:find).with(User, user.id.to_s)
|
16
|
+
PerformLater::Plugins.add_finder(CustomFinder)
|
17
|
+
|
18
|
+
subject.args_from_resque(["AR:User:#{user.id}"])
|
19
|
+
|
20
|
+
PerformLater::Plugins.clear_finder!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
7
24
|
context "args to resque" do
|
8
25
|
|
9
26
|
it "should convert array of hashes correctly" do
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'perform_later/plugins'
|
2
|
+
|
3
|
+
class BadDummyFinder
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
class GoodDummyFinder
|
8
|
+
def self.find(runner_class, id)
|
9
|
+
runner_class.find(id)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe PerformLater::Plugins do
|
14
|
+
subject { PerformLater::Plugins }
|
15
|
+
|
16
|
+
describe :finder_class do
|
17
|
+
it "should be nil" do
|
18
|
+
subject.finder_class.should == nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe :add_finder do
|
23
|
+
it "should not add the finder since it doens't have the proper method" do
|
24
|
+
subject.add_finder(BadDummyFinder)
|
25
|
+
subject.finder_class.should == nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should add the finder since it has the proper method" do
|
29
|
+
subject.add_finder(GoodDummyFinder)
|
30
|
+
subject.finder_class.should == GoodDummyFinder
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -40,6 +40,15 @@ describe PerformLater::Workers::Objects::Worker do
|
|
40
40
|
subject.perform("DummyClass", :identity_function, args).should == user
|
41
41
|
end
|
42
42
|
|
43
|
+
it "should pass a single argument (user) when translated args are passed in" do
|
44
|
+
user = User.create
|
45
|
+
user_arg = "AR:User:#{user.id}"
|
46
|
+
mock_user = double(:user, first: nil)
|
47
|
+
User.should_receive(:where).with(id: user.id.to_s).and_return { mock_user }
|
48
|
+
|
49
|
+
subject.perform("DummyClass", :identity_function, user_arg).should == nil
|
50
|
+
end
|
51
|
+
|
43
52
|
it "should pass an array with one entry" do
|
44
53
|
users = [User.create]
|
45
54
|
args = PerformLater::ArgsParser.args_to_resque(users)
|
data/spec/spec_helper.rb
CHANGED
Binary file
|
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: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -191,10 +191,12 @@ files:
|
|
191
191
|
- lib/perform_later/args_parser.rb
|
192
192
|
- lib/perform_later/config.rb
|
193
193
|
- lib/perform_later/payload_helper.rb
|
194
|
+
- lib/perform_later/plugins.rb
|
194
195
|
- lib/perform_later/railtie.rb
|
195
196
|
- lib/perform_later/version.rb
|
196
197
|
- lib/perform_later/workers/active_record/lone_worker.rb
|
197
198
|
- lib/perform_later/workers/active_record/worker.rb
|
199
|
+
- lib/perform_later/workers/base.rb
|
198
200
|
- lib/perform_later/workers/objects/lone_worker.rb
|
199
201
|
- lib/perform_later/workers/objects/worker.rb
|
200
202
|
- lib/resque/plugins/later/method.rb
|
@@ -205,6 +207,7 @@ files:
|
|
205
207
|
- spec/lib/perform_later/args_parser_spec.rb
|
206
208
|
- spec/lib/perform_later/config_spec.rb
|
207
209
|
- spec/lib/perform_later/payload_helper_spec.rb
|
210
|
+
- spec/lib/perform_later/plugins_spec.rb
|
208
211
|
- spec/lib/perform_later/workers/active_record/worker_spec.rb
|
209
212
|
- spec/lib/perform_later/workers/objects/worker_spec.rb
|
210
213
|
- spec/lib/perform_later_spec.rb
|
@@ -244,6 +247,7 @@ test_files:
|
|
244
247
|
- spec/lib/perform_later/args_parser_spec.rb
|
245
248
|
- spec/lib/perform_later/config_spec.rb
|
246
249
|
- spec/lib/perform_later/payload_helper_spec.rb
|
250
|
+
- spec/lib/perform_later/plugins_spec.rb
|
247
251
|
- spec/lib/perform_later/workers/active_record/worker_spec.rb
|
248
252
|
- spec/lib/perform_later/workers/objects/worker_spec.rb
|
249
253
|
- spec/lib/perform_later_spec.rb
|