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 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.later.enabled = true # this will default to false if unset
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
 
@@ -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
- when CLASS_STRING_FORMAT then $1.constantize
22
- when AR_STRING_FORMAT then $1.constantize.find_by_id($2)
23
- when YAML_STRING_FORMAT then YAML.load(o)
24
- else o
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,3 +1,3 @@
1
1
  module PerformLater
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  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 = eval(klass)
11
+ runner_klass = klass.constantize
12
12
 
13
- record = runner_klass.where(:id => id).first
14
-
15
- if args.length > 0
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 = eval(klass)
7
+ runner_klass = klass.constantize
8
8
 
9
- record = runner_klass.where(:id => id).first
9
+ record = runner_klass.find(id)
10
10
 
11
- if args.length > 0
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
- args = PerformLater::ArgsParser.args_from_resque(args)
9
+ arguments = PerformLater::ArgsParser.args_from_resque(args)
11
10
 
12
- if args.length > 0
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
- if arguments.any?
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)
@@ -27,6 +27,7 @@ RSpec.configure do |config|
27
27
  end
28
28
 
29
29
  config.after(:each) do
30
+ PerformLater::Plugins.clear_finder!
30
31
  $redis.flushdb
31
32
  end
32
33
  end
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.2.0
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-25 00:00:00.000000000 Z
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