taskinator 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f681b5a701e5f68d9bb53ac6edf88480c7ddbfa9
4
- data.tar.gz: 0b2f8046ada412f50927cd76d4989f98dfeff452
3
+ metadata.gz: 75ca53362ea028543eae463a901056c08049ecd7
4
+ data.tar.gz: 7971999d4c6c962c057329ba215394af3830ac5f
5
5
  SHA512:
6
- metadata.gz: ed37c8d1d8974b9bb22ab1b95baa4448e16ecf2faebbe3a72c815b692ac8286714849d2ee8662f2b9c78cfcb3066ac183fb5da0983006f9ed51046e193bdcdd9
7
- data.tar.gz: 720b6d27cce9bf6728d333faf65d4db46e3c91cc326783465d7133fd86673fa3ec57d5c19646028c0781c124afa36e3d89bc68b31cec6a13b79024cd96214a44
6
+ metadata.gz: ae31ec1d8ce1ca9c16aa38425150525c3b7c9e51cc2991935ea42522e63f05e217b3e179403eebcd9fc2d48d8c512375074dc53fd3ee2c262aeb19effd146179
7
+ data.tar.gz: aa3e70be0f952329ce8857d1e74aac32395f27c72848af95aad81a61e6adbd8098933d8ee38ec6b9e8f792e5f82684c02afddf9a51b91ffcc63b2408f64b1783
data/Gemfile.lock CHANGED
@@ -8,7 +8,7 @@ GIT
8
8
  PATH
9
9
  remote: .
10
10
  specs:
11
- taskinator (0.0.8)
11
+ taskinator (0.0.9)
12
12
  connection_pool (>= 2.0.0)
13
13
  json (>= 1.8.1)
14
14
  redis (>= 3.0.6)
@@ -24,7 +24,7 @@ module Taskinator
24
24
  raise ArgumentError, 'block' unless block_given?
25
25
 
26
26
  sub_process = Process.define_sequential_process_for(@definition, options)
27
- Builder.new(define_sub_process_task(@process, sub_process, options), @definition, @args).instance_eval(&block)
27
+ Builder.new(define_sub_process_task(@process, sub_process, options), @definition, *@args).instance_eval(&block)
28
28
  end
29
29
 
30
30
  # defines a sub process of tasks which are executed concurrently
@@ -32,7 +32,7 @@ module Taskinator
32
32
  raise ArgumentError, 'block' unless block_given?
33
33
 
34
34
  sub_process = Process.define_concurrent_process_for(@definition, complete_on, options)
35
- Builder.new(define_sub_process_task(@process, sub_process, options), @definition, @args).instance_eval(&block)
35
+ Builder.new(define_sub_process_task(@process, sub_process, options), @definition, *@args).instance_eval(&block)
36
36
  end
37
37
 
38
38
  # dynamically defines tasks, using the given @iterator method
@@ -43,7 +43,7 @@ module Taskinator
43
43
  raise ArgumentError, 'block' unless block_given?
44
44
 
45
45
  @executor.send(method, *[*@args, options]) do |*args|
46
- Builder.new(@process, @definition, args).instance_eval(&block)
46
+ Builder.new(@process, @definition, *args).instance_eval(&block)
47
47
  end
48
48
  end
49
49
 
@@ -76,7 +76,7 @@ module Taskinator
76
76
  # TODO: decide whether the sub process to dynamically receive arguments
77
77
 
78
78
  sub_process = definition.create_process(*@args)
79
- Builder.new(define_sub_process_task(@process, sub_process, options), definition, @args)
79
+ Builder.new(define_sub_process_task(@process, sub_process, options), definition, *@args)
80
80
  end
81
81
 
82
82
  private
@@ -13,6 +13,7 @@ module Taskinator
13
13
  task.perform &block
14
14
  task.complete!
15
15
  rescue Exception => e
16
+ Taskinator.logger.error(e)
16
17
  task.fail!(e)
17
18
  raise e
18
19
  end
@@ -57,12 +57,17 @@ module Taskinator
57
57
  state :initial do
58
58
  event :enqueue, :transitions_to => :enqueued
59
59
  event :start, :transitions_to => :processing
60
+
61
+ # need to be able to complete, for when there are no tasks
62
+ event :complete, :transitions_to => :completed, :if => :no_tasks_defined?
63
+
60
64
  event :cancel, :transitions_to => :cancelled
61
65
  event :fail, :transitions_to => :failed
62
66
  end
63
67
 
64
68
  state :enqueued do
65
69
  event :start, :transitions_to => :processing
70
+ event :complete, :transitions_to => :completed, :if => :no_tasks_defined?
66
71
  event :cancel, :transitions_to => :cancelled
67
72
  event :fail, :transitions_to => :failed
68
73
  end
@@ -89,15 +94,25 @@ module Taskinator
89
94
 
90
95
  on_error do |error, from, to, event, *args|
91
96
  Taskinator.logger.error("PROCESS: #{self.class.name}:#{uuid} :: #{error.message}")
97
+ Taskinator.logger.debug(error.backtrace)
92
98
  fail!(error)
93
99
  end
94
100
  end
95
101
 
102
+ def no_tasks_defined?
103
+ tasks.empty?
104
+ end
105
+
96
106
  def tasks_completed?(*args)
97
107
  # subclasses must implement this method
98
108
  raise NotImplementedError
99
109
  end
100
110
 
111
+ def task_failed(task, error)
112
+ # for now, fail this process
113
+ fail!(error)
114
+ end
115
+
101
116
  # include after defining the workflow
102
117
  # since the load and persist state methods
103
118
  # need to override the ones defined by workflow
@@ -114,6 +129,13 @@ module Taskinator
114
129
  parent.complete! unless parent.nil?
115
130
  end
116
131
 
132
+ # callback for when the process has failed
133
+ def on_failed_entry(*args)
134
+ # notify the parent task (if there is one) that this process has failed
135
+ # note: parent may be a proxy, so explicity check for nil?
136
+ parent.fail!(*args) unless parent.nil?
137
+ end
138
+
117
139
  class Sequential < Process
118
140
  def start
119
141
  task = tasks.first
@@ -157,7 +179,7 @@ module Taskinator
157
179
 
158
180
  def task_completed(task)
159
181
  # when complete on first, then don't bother with subsequent tasks completing
160
- return if completed?
182
+ return if completed? || failed?
161
183
  complete! if can_complete?
162
184
  end
163
185
 
@@ -10,6 +10,7 @@ module Taskinator
10
10
  begin
11
11
  process.start!
12
12
  rescue Exception => e
13
+ Taskinator.logger.error(e)
13
14
  process.fail!(e)
14
15
  raise e
15
16
  end
@@ -60,6 +60,10 @@ module Taskinator
60
60
 
61
61
  state :enqueued do
62
62
  event :start, :transitions_to => :processing
63
+
64
+ # need to be able to complete, for when sub-tasks have no tasks
65
+ event :complete, :transitions_to => :completed, :if => :can_complete_task?
66
+
63
67
  event :fail, :transitions_to => :failed
64
68
  end
65
69
 
@@ -77,6 +81,7 @@ module Taskinator
77
81
 
78
82
  on_error do |error, from, to, event, *args|
79
83
  Taskinator.logger.error("TASK: #{self.class.name}:#{uuid} :: #{error.message}")
84
+ Taskinator.logger.debug(error.backtrace)
80
85
  fail!(error)
81
86
  end
82
87
  end
@@ -101,6 +106,12 @@ module Taskinator
101
106
  process.task_completed(self)
102
107
  end
103
108
 
109
+ # callback for when the task has failed
110
+ def on_failed_entry(*args)
111
+ # notify the process that this task has failed
112
+ process.task_failed(self, args.last)
113
+ end
114
+
104
115
  # helper method, delegating to process
105
116
  def paused?
106
117
  process.paused?
@@ -11,6 +11,7 @@ module Taskinator
11
11
  task.start!
12
12
  task.complete! if task.can_complete?
13
13
  rescue Exception => e
14
+ Taskinator.logger.error(e)
14
15
  task.fail!(e)
15
16
  raise e
16
17
  end
@@ -1,3 +1,3 @@
1
1
  module Taskinator
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -157,13 +157,21 @@ describe Taskinator::Process do
157
157
  end
158
158
 
159
159
  describe "#parent" do
160
- it "notifies parent" do
160
+ it "notifies parent when completed" do
161
161
  allow(subject).to receive(:tasks_completed?) { true }
162
162
  subject.parent = double('parent')
163
163
  expect(subject.parent).to receive(:complete!)
164
164
  subject.start!
165
165
  subject.complete!
166
166
  end
167
+
168
+ it "notifies parent when failed" do
169
+ allow(subject).to receive(:tasks_completed?) { true }
170
+ subject.parent = double('parent')
171
+ expect(subject.parent).to receive(:fail!)
172
+ subject.start!
173
+ subject.fail!
174
+ end
167
175
  end
168
176
 
169
177
  describe "persistence" do
@@ -351,6 +359,16 @@ describe Taskinator::Process do
351
359
  end
352
360
  end
353
361
 
362
+ describe "#task_failed" do
363
+ it "fails when tasks fail" do
364
+ tasks.each {|t| subject.tasks << t }
365
+
366
+ expect(subject).to receive(:fail!).with(StandardError)
367
+
368
+ subject.task_failed(tasks.first, StandardError)
369
+ end
370
+ end
371
+
354
372
  describe "#tasks_completed?" do
355
373
 
356
374
  describe "complete on first" do
@@ -96,6 +96,7 @@ describe Taskinator::Task do
96
96
  it { expect(subject).to respond_to(:fail!) }
97
97
  it {
98
98
  expect(subject).to receive(:fail).with(StandardError)
99
+ expect(process).to receive(:task_failed).with(subject, StandardError)
99
100
  subject.start!
100
101
  subject.fail!(StandardError)
101
102
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taskinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Stefano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-11 00:00:00.000000000 Z
11
+ date: 2014-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis