taskinator 0.0.8 → 0.0.9

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,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