perform_later 1.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|