perform_later 1.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +89 -24
- data/lib/object_perform_later.rb +5 -2
- data/lib/perform_later/railtie.rb +1 -1
- data/lib/perform_later/version.rb +1 -1
- data/lib/perform_later.rb +3 -4
- data/perform_later.gemspec +1 -0
- data/spec/lib/perform_later/config_spec.rb +1 -1
- data/spec/lib/resque/plugins/later/method_spec.rb +0 -1
- data/spec/spec_helper.rb +2 -1
- data/spec/support/database_models.rb +7 -6
- metadata +17 -2
- data/lib/object_worker.rb +0 -12
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
## Overview
|
4
4
|
Perform later is a gem meant to work with the [Resque](http://github.com/defunkt/resque) queue system.
|
5
5
|
|
6
|
-
|
6
|
+
Usually, when working with Resque, you need separate "Worker" classes and you also need to do `Resque.enqueue` whenever you want to add a task to the queue.
|
7
7
|
|
8
|
-
|
8
|
+
That can be a real hassle if you are adding Resque to an existing project, it can also add quite a bit of code to your system.
|
9
9
|
|
10
|
-
|
10
|
+
`perform_later` fills this need, it offers a suite to handle all of your queuing needs, both for Objects and for ActiveRecord models.
|
11
11
|
|
12
12
|
## Why?
|
13
13
|
*Why* should you queue something for later?
|
@@ -17,55 +17,120 @@ You should queue something whenever the method handles some heavy lifting, some
|
|
17
17
|
The basic logic is that whatever you don't need to do NOW, you should do later, this will make your site faster and the users will feel it.
|
18
18
|
|
19
19
|
## Real life use case
|
20
|
-
At [Gogobot](http://gogobot.com) whenever you post a review, there's major score calculation going on
|
20
|
+
At [Gogobot](http://gogobot.com) whenever you post a review, there's major score calculation going on. This can sometimes take up to a minute, depending on the user graph.
|
21
21
|
|
22
22
|
The user should not wait for this on submit, it can be queued into later execution.
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
## Installation
|
25
|
+
gem install perform_later
|
26
26
|
|
27
|
-
|
27
|
+
If you are using bundler, simply add
|
28
|
+
`gem "perform_later"` to your Gemfile
|
29
|
+
|
30
|
+
|
31
|
+
## Configuration
|
32
|
+
You can configure `perform_later` exactly as you configure your rails app.
|
33
|
+
|
34
|
+
Inside your `#{env}.rb` file (for example development.rb)
|
28
35
|
|
29
36
|
```ruby
|
30
|
-
|
31
|
-
:method_name #the method that will be called on the object
|
32
|
-
args #array of arguments
|
37
|
+
config.later.enabled = true # this will default to false if unset
|
33
38
|
```
|
34
39
|
|
35
|
-
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
### ActiveRecord
|
43
|
+
|
44
|
+
`perform_later` comes with a special method you can use on ActiveRecord models.
|
45
|
+
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
|
49
|
+
class User < ActiveRecord::Base
|
50
|
+
def long_running_method
|
51
|
+
# Your code here
|
52
|
+
end
|
53
|
+
later :long_running_method
|
54
|
+
|
55
|
+
def long_running_method_2
|
56
|
+
# Your code here
|
57
|
+
end
|
58
|
+
later :long_running_method_2, queue: :some_queue_name
|
59
|
+
|
60
|
+
def lonely_long_running_method
|
61
|
+
# Your code here
|
62
|
+
end
|
63
|
+
later :lonely_long_running_method, :loner => true, queue: :some_queue_name
|
64
|
+
end
|
65
|
+
|
66
|
+
```
|
36
67
|
|
37
68
|
```ruby
|
38
|
-
|
39
|
-
|
69
|
+
u = User.find(some_user_id)
|
70
|
+
u.long_running_method # Method will be queued into the :generic queue
|
71
|
+
u.long_running_method_2 # Method will be queued into :some_queue_name queue
|
72
|
+
u.lonely_long_running_method # Method will be queued into the :some_queue_name queue, only a single instance of this method can exist in the queue.
|
40
73
|
```
|
41
74
|
|
42
|
-
You can
|
75
|
+
You can of course choose to run the method off the queue, just prepend `now_` to the method name and it will be executed in sync.
|
43
76
|
|
44
77
|
```ruby
|
45
|
-
User.
|
78
|
+
u = User.find(some_user_id)
|
79
|
+
u.now_long_running_method
|
46
80
|
```
|
47
81
|
|
82
|
+
### Objects/Classes
|
48
83
|
|
84
|
+
If you want object methods to be queued, you will have to use the `perform_later` special method.
|
49
85
|
|
50
|
-
|
51
|
-
|
86
|
+
```ruby
|
87
|
+
class SomeClass
|
88
|
+
def some_heavy_lifting_method
|
89
|
+
# Your code here
|
90
|
+
end
|
91
|
+
|
92
|
+
def some_more_heavy_lifting(user_id)
|
93
|
+
# Your code here
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
SomeClass.perform_later(:queue_name, :some_heavy_lifting_method)
|
98
|
+
SomeClass.perform_later(:queue_name, :some_more_heavy_lifting, user_id)
|
99
|
+
```
|
52
100
|
|
53
|
-
|
101
|
+
## The params parser
|
102
|
+
`perform_later` has a special class called `ArgsParser`, this class is in charge of *translating* the args you are passing into params that can actually be serialized to JSON cleanly.
|
103
|
+
|
104
|
+
Examples:
|
54
105
|
|
55
106
|
```ruby
|
56
|
-
|
107
|
+
user = User.find(1)
|
108
|
+
PerformLater::ArgsParser.params_to_resque(user) => 'AR:#User:1'
|
109
|
+
|
110
|
+
hotel = Hotel.find(1)
|
111
|
+
PerformLater::ArgsParser.params_to_resque(hotel) => 'AR:#Hotel:1'
|
112
|
+
|
113
|
+
hash = { name: "something", other: "something else" }
|
114
|
+
PerformLater::ArgsParser.params_to_resque(hash)
|
115
|
+
=> ---
|
116
|
+
:name: something
|
117
|
+
:other: something else
|
118
|
+
# Hashes are translated into YAML
|
57
119
|
```
|
58
120
|
|
59
|
-
|
60
|
-
|
61
|
-
|
121
|
+
Basically, the `ArgsParser` class allows you to keep passing any args you want to your methods without worrying about whether they serialize cleanly or not.
|
122
|
+
|
123
|
+
`ArgsParser` also patched `resque-mailer` so you can pass in AR objects to mailers as well.
|
62
124
|
|
125
|
+
|
63
126
|
## Contribute / Bug reports
|
127
|
+
|
64
128
|
If you have an issue with this gem, please open an issue in the main repo, it will help tons if you could supply a failing spec with that, so I can better track where the bug is coming from, if not, no worries, just report I will do my best to address it as fast and efficient as I can.
|
65
129
|
|
66
130
|
If you want to contribute (awesome), open a feature branch, base it on master.
|
67
131
|
|
68
132
|
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.
|
69
133
|
|
70
|
-
##
|
71
|
-
|
134
|
+
## Author
|
135
|
+
|
136
|
+
Avi Tzurel ([@kensodev](http://twitter.com/kensodev)) http://www.kensodev.com
|
data/lib/object_perform_later.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
module ObjectPerformLater
|
2
|
+
|
2
3
|
def perform_later(queue, method, *args)
|
3
4
|
if PerformLater.config.enabled?
|
4
5
|
args = PerformLater::ArgsParser.args_to_resque(args)
|
5
|
-
Resque::Job.create(queue,
|
6
|
+
Resque::Job.create(queue, PerformLater::Workers::Objects::Worker, self.name, method, *args)
|
6
7
|
else
|
7
8
|
self.send(method, *args)
|
8
9
|
end
|
9
10
|
end
|
11
|
+
|
10
12
|
end
|
11
13
|
|
12
|
-
Object.send
|
14
|
+
Object.send(:include, ObjectPerformLater)
|
15
|
+
|
data/lib/perform_later.rb
CHANGED
@@ -6,10 +6,11 @@ require 'resque-loner'
|
|
6
6
|
require 'perform_later/args_parser'
|
7
7
|
require 'active_record'
|
8
8
|
require 'resque_mailer_patch'
|
9
|
-
require 'object_worker'
|
10
9
|
require 'object_perform_later'
|
11
10
|
require 'perform_later/workers/active_record/worker'
|
12
11
|
require 'perform_later/workers/active_record/lone_worker'
|
12
|
+
require 'perform_later/workers/objects/worker'
|
13
|
+
require 'perform_later/workers/objects/lone_worker'
|
13
14
|
|
14
15
|
module PerformLater
|
15
16
|
def self.config
|
@@ -27,6 +28,4 @@ end
|
|
27
28
|
|
28
29
|
ActiveSupport.on_load(:active_record) do
|
29
30
|
include Resque::Plugins::Later::Method
|
30
|
-
end
|
31
|
-
|
32
|
-
|
31
|
+
end
|
data/perform_later.gemspec
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
class User < ActiveRecord::Base
|
2
2
|
def long_running_method
|
3
|
-
|
3
|
+
# Your code here
|
4
4
|
end
|
5
5
|
later :long_running_method
|
6
6
|
|
7
|
-
def
|
8
|
-
|
7
|
+
def long_running_method_2
|
8
|
+
# Your code here
|
9
9
|
end
|
10
|
-
later :
|
10
|
+
later :long_running_method_2, queue: :some_queue_name
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def lonely_long_running_method
|
13
|
+
# Your code here
|
14
14
|
end
|
15
|
+
later :lonely_long_running_method, :loner => true, queue: :some_queue_name
|
15
16
|
end
|
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.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -171,6 +171,22 @@ dependencies:
|
|
171
171
|
- - ! '>='
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: simplecov
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
174
190
|
description: Queue any method in any class or instance with no need for additional
|
175
191
|
Worker class and no extra code
|
176
192
|
email:
|
@@ -187,7 +203,6 @@ files:
|
|
187
203
|
- Rakefile
|
188
204
|
- init.rb
|
189
205
|
- lib/object_perform_later.rb
|
190
|
-
- lib/object_worker.rb
|
191
206
|
- lib/perform_later.rb
|
192
207
|
- lib/perform_later/args_parser.rb
|
193
208
|
- lib/perform_later/config.rb
|
data/lib/object_worker.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
class ObjectWorker
|
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_name, method, *args)
|
9
|
-
args = PerformLater::ArgsParser.args_from_resque(args)
|
10
|
-
klass_name.constantize.send(method, *args)
|
11
|
-
end
|
12
|
-
end
|