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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjU1OTk3MjUyZjViM2JhMzczZTk2MGFmZTc3YjU5YzY1NzI1ZjBiZg==
4
+ MjBhMmYyZDQ1ZmFkMDczYzI1OGZmYjY5YmZjYmYxMGRlZTU2ZDJhZQ==
5
5
  data.tar.gz: !binary |-
6
- NDA4OTYxMmI4MjA3YWM1ZDg2ZDVhZmJlYWQ4YWQ1ZWQ1NjA2OGY5Nw==
6
+ NTZmMjhhYzU5Y2Q2YzA0M2ZiM2M3MjFhZmNlYjU3YjdlMjM2YjJmNg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OGI4MWY0MDFlYmY1ZmY2NjI3YzUzNDk4MzAxNzZkYWFmOGZlNzI5NTViYTFk
10
- MmI2ODZmY2MxNTAwNTYyYmI0YTMzNzQyYTk5OWE4ZDcyZTA3ZWI1OWRlYzMw
11
- NjRjZDFlZDI2NDVjYzNmNzc3OTBjN2Y4MDdkZTA1ZDdmNDc0N2U=
9
+ ZjAxNTY4YzQ5OGI0MmIzYjA5YzFkYWYwZDFmZmZlYjJkYjVhNzFhZjkwYjZj
10
+ Yzg4NDEyZGRjOTM0MmU5OGQxOWRmNGJjN2FlYzg2YmYzNmQxNWVkZDlhMDUw
11
+ YTE4ZjlhZGI5OWMwYjBhNTc4Mjg3OTI2MzM0ZGI5YzM2NWUwMWM=
12
12
  data.tar.gz: !binary |-
13
- MjhkYjU5NThmMzI0M2JmZjJmZWJhYjI3MGQzMjdjNjliOGJmMGFmMDcxNzg3
14
- ZmNlZmQ5YjIxYTg1MjUzNTM2ZGUzNzc3NDczNDU5ZTAyOWQ1ZTE1YjNhNDQ1
15
- ZWJkODI3NGY2ZGY2NmFkZjJkMzk5YTA2MzEwMjcyZTc5NGViYzQ=
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` gem.
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
- transition any => options[:state]
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))
@@ -1,3 +1,3 @@
1
1
  module StateMachineJob
2
- VERSION = '0.0.6'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -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.6
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-01 00:00:00.000000000 Z
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.1.11
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.