state_machine_job 0.0.6 → 0.1.0
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.
- checksums.yaml +8 -8
- data/README.md +29 -6
- data/lib/state_machine_job/macro.rb +16 -1
- data/lib/state_machine_job/version.rb +1 -1
- data/spec/state_machine_job/macro_spec.rb +116 -0
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MjBhMmYyZDQ1ZmFkMDczYzI1OGZmYjY5YmZjYmYxMGRlZTU2ZDJhZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NTZmMjhhYzU5Y2Q2YzA0M2ZiM2M3MjFhZmNlYjU3YjdlMjM2YjJmNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjAxNTY4YzQ5OGI0MmIzYjA5YzFkYWYwZDFmZmZlYjJkYjVhNzFhZjkwYjZj
|
10
|
+
Yzg4NDEyZGRjOTM0MmU5OGQxOWRmNGJjN2FlYzg2YmYzNmQxNWVkZDlhMDUw
|
11
|
+
YTE4ZjlhZGI5OWMwYjBhNTc4Mjg3OTI2MzM0ZGI5YzM2NWUwMWM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZDc0MDZiNTVkMDI0MGJjNTgxYjRjODFkMGRjYmFjYzIxYzI2YjhmNDRjNmFj
|
14
|
+
NmU1YTQwNDQ1NWQ1NzJkNmFlNzI2MDQxZDQ5YjY5ODk0MzViODkxM2E5ODZj
|
15
|
+
MTc2OTU1MDQwYjc3YzEwNDcwMjQ2MjlhZjMxOWFhZjg1MmM3Nzg=
|
data/README.md
CHANGED
@@ -12,6 +12,9 @@ Add this line to your application's Gemfile:
|
|
12
12
|
|
13
13
|
gem 'state_machine_job'
|
14
14
|
|
15
|
+
Requires the [resque-logger](https://github.com/salizzar/resque-logger)
|
16
|
+
gem to be present and configured.
|
17
|
+
|
15
18
|
## Usage
|
16
19
|
|
17
20
|
Extend your resque job with the `StateMachineJob` mixin and provide a
|
@@ -48,10 +51,6 @@ Now you can wire up the job in a state machine using the
|
|
48
51
|
job SomeJob do
|
49
52
|
on_enter 'running'
|
50
53
|
|
51
|
-
payload do |record|
|
52
|
-
{:some_attribute => record.some_attribute}
|
53
|
-
end
|
54
|
-
|
55
54
|
result :ok => 'done'
|
56
55
|
result :error => 'failed'
|
57
56
|
end
|
@@ -84,7 +83,7 @@ method using the `payload` method:
|
|
84
83
|
`perform_with_result` is now called with the given hash of options as
|
85
84
|
the second parameter.
|
86
85
|
|
87
|
-
### Retrying Jobs
|
86
|
+
### Retrying Jobs after a Delay
|
88
87
|
|
89
88
|
You can tell the state machine to retry a job based on its result:
|
90
89
|
|
@@ -98,4 +97,28 @@ You can tell the state machine to retry a job based on its result:
|
|
98
97
|
|
99
98
|
When `perform_with_result` returns the result `:pending`, the state
|
100
99
|
machine will remain in the `runnning` state and enqueue a delayed
|
101
|
-
job. This functionality requires the `resque-scheduler`
|
100
|
+
job. This functionality requires the [`resque-scheduler`](https://github.com/resque/resque-scheduler)
|
101
|
+
gem.
|
102
|
+
|
103
|
+
### Retrying Jobs Based on State
|
104
|
+
|
105
|
+
You can tell the state machine to retry a job if a transition to a
|
106
|
+
certain state occures while a job is running:
|
107
|
+
|
108
|
+
event :run do
|
109
|
+
transition 'idle' => 'running'
|
110
|
+
transition 'running' => 'rerun_requested'
|
111
|
+
end
|
112
|
+
|
113
|
+
job SomeJob do
|
114
|
+
on_enter 'running'
|
115
|
+
|
116
|
+
result :ok, :state => 'done', :retry_if_state => 'rerun_requested'
|
117
|
+
result :error => 'failed'
|
118
|
+
end
|
119
|
+
|
120
|
+
If the `run` event is invoked while the job is already running, you
|
121
|
+
can transition to a state signaling that the job will need to run
|
122
|
+
again once it has finished. In example, passing the `:retry_if_state`
|
123
|
+
option causes the state machine to transition back to the `running`
|
124
|
+
state once the job finishes with result `:ok`.
|
@@ -19,9 +19,23 @@ module StateMachineJob
|
|
19
19
|
return result(job_result.first.first, :state => job_result.first.last)
|
20
20
|
end
|
21
21
|
|
22
|
+
if options[:retry_if_state] && options[:retry_after]
|
23
|
+
raise('Combining the :retry_after and :retry_on_state options is not supported at the moment.')
|
24
|
+
end
|
25
|
+
|
26
|
+
if options[:retry_if_state] && !@on_enter_state
|
27
|
+
raise('The on_enter call must appear above any result using the :retry_if_state option.')
|
28
|
+
end
|
29
|
+
|
30
|
+
on_enter_state = @on_enter_state
|
31
|
+
|
22
32
|
if options[:state]
|
23
33
|
@state_machine.event(job_result_event_name(job_result)) do
|
24
|
-
|
34
|
+
if options[:retry_if_state]
|
35
|
+
transition options[:retry_if_state] => on_enter_state
|
36
|
+
end
|
37
|
+
|
38
|
+
transition all => options[:state]
|
25
39
|
end
|
26
40
|
elsif options[:retry_after]
|
27
41
|
@state_machine.define_helper :instance, retry_job_method_name(job_result) do |machine, object|
|
@@ -32,6 +46,7 @@ module StateMachineJob
|
|
32
46
|
|
33
47
|
def on_enter(state)
|
34
48
|
job, state_machine, queue = @job, @state_machine, @queue
|
49
|
+
@on_enter_state = state
|
35
50
|
|
36
51
|
@state_machine.after_transition @state_machine.any => state do |object|
|
37
52
|
queue.enqueue(job, object.class.name, object.id, @payload.call(object))
|
@@ -144,5 +144,121 @@ module StateMachineJob
|
|
144
144
|
|
145
145
|
expect(object.state).to eq('done')
|
146
146
|
end
|
147
|
+
|
148
|
+
describe ':retry_if_state option' do
|
149
|
+
it 'returns to on_enter state if state matches option when job finishes' do
|
150
|
+
queue = double('queue')
|
151
|
+
object = Class.new do
|
152
|
+
def id
|
153
|
+
43
|
154
|
+
end
|
155
|
+
|
156
|
+
state_machine :initial => :idle do
|
157
|
+
extend StateMachineJob::Macro
|
158
|
+
|
159
|
+
state :idle
|
160
|
+
state :running
|
161
|
+
state :done
|
162
|
+
state :failed
|
163
|
+
|
164
|
+
event :run do
|
165
|
+
transition :idle => :running
|
166
|
+
transition :running => :rerun_required
|
167
|
+
end
|
168
|
+
|
169
|
+
job TestJob, queue do
|
170
|
+
on_enter :running
|
171
|
+
result :ok, :state => :done, :retry_if_state => :rerun_required
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end.new
|
175
|
+
|
176
|
+
expect(queue).to receive(:enqueue).with(TestJob, nil, 43, {})
|
177
|
+
|
178
|
+
object.state = :running
|
179
|
+
object.run
|
180
|
+
object.state_machine_job_test_job_ok
|
181
|
+
|
182
|
+
expect(object.state).to eq('running')
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'returns to result state if state does not match option when job finishes' do
|
186
|
+
queue = double('queue')
|
187
|
+
object = Class.new do
|
188
|
+
def id
|
189
|
+
43
|
190
|
+
end
|
191
|
+
|
192
|
+
state_machine :initial => :idle do
|
193
|
+
extend StateMachineJob::Macro
|
194
|
+
|
195
|
+
state :idle
|
196
|
+
state :running
|
197
|
+
state :done
|
198
|
+
state :failed
|
199
|
+
|
200
|
+
event :run do
|
201
|
+
transition :idle => :running
|
202
|
+
transition :running => :rerun_required
|
203
|
+
end
|
204
|
+
|
205
|
+
job TestJob, queue do
|
206
|
+
on_enter :running
|
207
|
+
result :ok, :state => :done, :retry_if_state => :rerun_required
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end.new
|
211
|
+
|
212
|
+
object.state = :running
|
213
|
+
object.state_machine_job_test_job_ok
|
214
|
+
|
215
|
+
expect(object.state).to eq('done')
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'raises descriptive error when on_enter is used after result' do
|
219
|
+
expect {
|
220
|
+
Class.new do
|
221
|
+
state_machine :initial => :idle do
|
222
|
+
extend StateMachineJob::Macro
|
223
|
+
|
224
|
+
job TestJob do
|
225
|
+
result :ok, :state => :done, :retry_if_state => :rerun_required
|
226
|
+
on_enter :running
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
}.to raise_error(/on_enter call must appear above any result/)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'raises descriptive error when used in combination with :retry_after option' do
|
234
|
+
expect {
|
235
|
+
Class.new do
|
236
|
+
state_machine :initial => :idle do
|
237
|
+
extend StateMachineJob::Macro
|
238
|
+
|
239
|
+
job TestJob do
|
240
|
+
on_enter :running
|
241
|
+
result :ok, :state => :done, :retry_if_state => :rerun_required, :retry_after => 100
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
}.to raise_error(/not supported/)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'does not raise exception if on_enter is used after result without :retry_if_state option' do
|
250
|
+
expect {
|
251
|
+
Class.new do
|
252
|
+
state_machine :initial => :idle do
|
253
|
+
extend StateMachineJob::Macro
|
254
|
+
|
255
|
+
job TestJob do
|
256
|
+
result :ok, :state => :done
|
257
|
+
on_enter :running
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
}.not_to raise_error
|
262
|
+
end
|
147
263
|
end
|
148
264
|
end
|
metadata
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: state_machine_job
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Codevise Solutions Ltd.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
|
-
type: :development
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
16
|
requirements:
|
18
17
|
- - ~>
|
19
18
|
- !ruby/object:Gem::Version
|
20
19
|
version: '1.3'
|
20
|
+
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
@@ -26,12 +26,12 @@ dependencies:
|
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
|
-
type: :development
|
30
29
|
requirement: !ruby/object:Gem::Requirement
|
31
30
|
requirements:
|
32
31
|
- - ! '>='
|
33
32
|
- !ruby/object:Gem::Version
|
34
33
|
version: '0'
|
34
|
+
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
@@ -40,12 +40,12 @@ dependencies:
|
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
|
-
type: :development
|
44
43
|
requirement: !ruby/object:Gem::Requirement
|
45
44
|
requirements:
|
46
45
|
- - ! '>='
|
47
46
|
- !ruby/object:Gem::Version
|
48
47
|
version: '0'
|
48
|
+
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
@@ -54,12 +54,12 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: activesupport
|
57
|
-
type: :development
|
58
57
|
requirement: !ruby/object:Gem::Requirement
|
59
58
|
requirements:
|
60
59
|
- - ! '>='
|
61
60
|
- !ruby/object:Gem::Version
|
62
61
|
version: '0'
|
62
|
+
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
@@ -68,12 +68,12 @@ dependencies:
|
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: resque
|
71
|
-
type: :runtime
|
72
71
|
requirement: !ruby/object:Gem::Requirement
|
73
72
|
requirements:
|
74
73
|
- - ! '>='
|
75
74
|
- !ruby/object:Gem::Version
|
76
75
|
version: '0'
|
76
|
+
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
@@ -82,12 +82,12 @@ dependencies:
|
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: resque-logger
|
85
|
-
type: :runtime
|
86
85
|
requirement: !ruby/object:Gem::Requirement
|
87
86
|
requirements:
|
88
87
|
- - ! '>='
|
89
88
|
- !ruby/object:Gem::Version
|
90
89
|
version: '0'
|
90
|
+
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
@@ -96,12 +96,12 @@ dependencies:
|
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: state_machine
|
99
|
-
type: :runtime
|
100
99
|
requirement: !ruby/object:Gem::Requirement
|
101
100
|
requirements:
|
102
101
|
- - ! '>='
|
103
102
|
- !ruby/object:Gem::Version
|
104
103
|
version: '0'
|
104
|
+
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
@@ -148,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
148
|
version: '0'
|
149
149
|
requirements: []
|
150
150
|
rubyforge_project:
|
151
|
-
rubygems_version: 2.
|
151
|
+
rubygems_version: 2.2.2
|
152
152
|
signing_key:
|
153
153
|
specification_version: 4
|
154
154
|
summary: Resque jobs class for rails state machines.
|