taskinator 0.4.7 → 0.5.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/{taskinator.yml → build.yml} +2 -15
  3. data/.github/workflows/release.yml +18 -0
  4. data/CHANGELOG.md +33 -1
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +64 -69
  7. data/README.md +50 -42
  8. data/lib/taskinator/builder.rb +129 -0
  9. data/lib/taskinator/definition.rb +2 -2
  10. data/lib/taskinator/instrumentation.rb +1 -0
  11. data/lib/taskinator/persistence.rb +51 -5
  12. data/lib/taskinator/process.rb +18 -9
  13. data/lib/taskinator/queues/active_job.rb +0 -12
  14. data/lib/taskinator/queues/delayed_job.rb +0 -11
  15. data/lib/taskinator/queues/resque.rb +0 -15
  16. data/lib/taskinator/queues/sidekiq.rb +0 -13
  17. data/lib/taskinator/queues.rb +0 -5
  18. data/lib/taskinator/task.rb +9 -11
  19. data/lib/taskinator/version.rb +1 -1
  20. data/lib/taskinator.rb +0 -14
  21. data/spec/support/test_job.rb +30 -0
  22. data/spec/support/test_job_task.rb +2 -0
  23. data/spec/support/test_queue.rb +21 -15
  24. data/spec/support/test_step_task.rb +2 -0
  25. data/spec/support/test_subprocess_task.rb +2 -0
  26. data/spec/taskinator/{definition/builder_spec.rb → builder_spec.rb} +2 -2
  27. data/spec/taskinator/definition_spec.rb +32 -1
  28. data/spec/taskinator/instrumentation_spec.rb +3 -2
  29. data/spec/taskinator/persistence_spec.rb +131 -5
  30. data/spec/taskinator/process_spec.rb +11 -3
  31. data/spec/taskinator/queues/active_job_spec.rb +0 -21
  32. data/spec/taskinator/queues/delayed_job_spec.rb +0 -18
  33. data/spec/taskinator/queues/resque_spec.rb +0 -21
  34. data/spec/taskinator/queues/sidekiq_spec.rb +0 -19
  35. data/spec/taskinator/queues/test_queue_adapter_spec.rb +9 -0
  36. data/spec/taskinator/task_spec.rb +43 -25
  37. data/spec/taskinator/taskinator_spec.rb +16 -0
  38. data/spec/taskinator/test_flows_spec.rb +16 -8
  39. data/taskinator.gemspec +2 -3
  40. metadata +21 -31
  41. data/lib/taskinator/definition/builder.rb +0 -129
  42. data/lib/taskinator/log_stats.rb +0 -49
  43. data/lib/taskinator/process_worker.rb +0 -13
  44. data/lib/taskinator/xml_visitor.rb +0 -109
  45. data/spec/taskinator/process_worker_spec.rb +0 -5
  46. data/spec/taskinator/xml_visitor_spec.rb +0 -5
@@ -1,3 +1,5 @@
1
+ require 'builder'
2
+
1
3
  module Taskinator
2
4
  module Persistence
3
5
 
@@ -447,6 +449,46 @@ module Taskinator
447
449
  end
448
450
  end
449
451
 
452
+ class UnknownTypeError < StandardError
453
+ end
454
+
455
+ module UnknownType
456
+
457
+ @unknown_types = {}
458
+
459
+ def self.new(type)
460
+ Taskinator.logger.error("Unknown type '#{type}' while deserializing.")
461
+ @unknown_types[type] ||= Module.new do
462
+ extend UnknownType
463
+ @type = type
464
+
465
+ # for unknown definitions
466
+ def method_missing(_, *_)
467
+ raise UnknownTypeError.new(to_s)
468
+ end
469
+ end
470
+ end
471
+
472
+ attr_reader :type
473
+
474
+ def to_s
475
+ "Unknown type '#{type}'."
476
+ end
477
+
478
+ def allocate
479
+ self
480
+ end
481
+
482
+ def accept(*_)
483
+ # nothing doing
484
+ end
485
+
486
+ # for unknown job types
487
+ def perform(*_)
488
+ raise UnknownTypeError.new(to_s)
489
+ end
490
+ end
491
+
450
492
  class RedisDeserializationVisitor < Taskinator::Visitor::Base
451
493
 
452
494
  #
@@ -480,7 +522,7 @@ module Taskinator
480
522
  return unless @attribute_values.key?(:type)
481
523
 
482
524
  type = @attribute_values[:type]
483
- klass = Kernel.const_get(type)
525
+ klass = Kernel.const_get(type) rescue UnknownType.new(type)
484
526
 
485
527
  #
486
528
  # NOTE:
@@ -539,16 +581,18 @@ module Taskinator
539
581
  def visit_attribute_enum(attribute, type)
540
582
  visit_attribute(attribute) do |value|
541
583
  const_value = type.constants.select {|c| type.const_get(c) == value.to_i }.first
542
- const_value ?
543
- type.const_get(const_value) :
544
- (defined?(type::Default) ? type::Default : nil)
584
+ if const_value
585
+ type.const_get(const_value)
586
+ else
587
+ defined?(type::Default) ? type::Default : nil
588
+ end
545
589
  end
546
590
  end
547
591
 
548
592
  def visit_type(attribute)
549
593
  value = @attribute_values[attribute]
550
594
  if value
551
- type = Kernel.const_get(value)
595
+ type = Kernel.const_get(value) rescue UnknownType.new(value)
552
596
  @instance.instance_variable_set("@#{attribute}", type)
553
597
  end
554
598
  end
@@ -576,6 +620,8 @@ module Taskinator
576
620
  type = Taskinator.redis do |conn|
577
621
  conn.hget(base.key_for(uuid), :type)
578
622
  end
623
+ # these types are always from taskinator
624
+ # so no need to rescue for unknown types!
579
625
  klass = Kernel.const_get(type)
580
626
  LazyLoader.new(klass, uuid, @instance_cache)
581
627
  end
@@ -48,6 +48,7 @@ module Taskinator
48
48
  @parent = value
49
49
  # update the uuid to be "scoped" within the parent task
50
50
  @uuid = "#{@parent.uuid}:subprocess"
51
+ @key = nil # NB: invalidate memoized key
51
52
  end
52
53
 
53
54
  def tasks
@@ -123,7 +124,7 @@ module Taskinator
123
124
  instrument('taskinator.process.completed', completed_payload) do
124
125
  complete if respond_to?(:complete)
125
126
  # notify the parent task (if there is one) that this process has completed
126
- # note: parent may be a proxy, so explicity check for nil?
127
+ # note: parent may be a proxy, so explicitly check for nil?
127
128
  unless parent.nil?
128
129
  parent.complete!
129
130
  else
@@ -133,6 +134,9 @@ module Taskinator
133
134
  end
134
135
  end
135
136
 
137
+ # TODO: add retry method - to pick up from a failed task
138
+ # e.g. like retrying a failed job in Resque Web
139
+
136
140
  def tasks_completed?
137
141
  # TODO: optimize this
138
142
  tasks.all?(&:completed?)
@@ -151,7 +155,7 @@ module Taskinator
151
155
  instrument('taskinator.process.failed', failed_payload(error)) do
152
156
  fail(error) if respond_to?(:fail)
153
157
  # notify the parent task (if there is one) that this process has failed
154
- # note: parent may be a proxy, so explicity check for nil?
158
+ # note: parent may be a proxy, so explicitly check for nil?
155
159
  parent.fail!(error) unless parent.nil?
156
160
  end
157
161
  end
@@ -166,6 +170,7 @@ module Taskinator
166
170
  # subclasses must implement the following methods
167
171
  #--------------------------------------------------
168
172
 
173
+ # :nocov:
169
174
  def enqueue
170
175
  raise NotImplementedError
171
176
  end
@@ -177,6 +182,7 @@ module Taskinator
177
182
  def task_completed(task)
178
183
  raise NotImplementedError
179
184
  end
185
+ # :nocov:
180
186
 
181
187
  #--------------------------------------------------
182
188
 
@@ -199,10 +205,9 @@ module Taskinator
199
205
  end
200
206
 
201
207
  def task_completed(task)
202
- # deincrement the count of pending sequential tasks
208
+ # decrement the count of pending sequential tasks
203
209
  pending = deincr_pending_tasks
204
210
 
205
- Taskinator.statsd_client.count("taskinator.#{definition.name.underscore.parameterize}.pending", pending)
206
211
  Taskinator.logger.info("Completed task for process '#{uuid}'. Pending is #{pending}.")
207
212
 
208
213
  next_task = task.next
@@ -222,19 +227,21 @@ module Taskinator
222
227
 
223
228
  class Concurrent < Process
224
229
  attr_reader :complete_on
230
+
231
+ # <b>DEPRECATED:</b> concurrency_method will be removed in a future version.
225
232
  attr_reader :concurrency_method
226
233
 
227
234
  def initialize(definition, complete_on=CompleteOn::Default, options={})
228
235
  super(definition, options)
229
236
  @complete_on = complete_on
230
237
  @concurrency_method = options.delete(:concurrency_method) || :thread
238
+ warn("[DEPRECATED]: concurrency_method will be removed in a future version.") if @concurrency_method == :fork
231
239
  end
232
240
 
233
241
  def enqueue
234
242
  if tasks.empty?
235
243
  complete! # weren't any tasks to start with
236
244
  else
237
- Taskinator.statsd_client.count("taskinator.#{definition.name.underscore.parameterize}.pending", tasks.count)
238
245
  Taskinator.logger.info("Enqueuing #{tasks.count} tasks for process '#{uuid}'.")
239
246
  tasks.each(&:enqueue!)
240
247
  end
@@ -246,12 +253,15 @@ module Taskinator
246
253
  complete! # weren't any tasks to start with
247
254
  else
248
255
  if concurrency_method == :fork
256
+ # :nocov:
257
+ warn("[DEPRECATED]: concurrency_method will be removed in a future version.")
249
258
  tasks.each do |task|
250
259
  fork do
251
260
  task.start!
252
261
  end
253
262
  end
254
263
  Process.waitall
264
+ # :nocov:
255
265
  else
256
266
  threads = tasks.map do |task|
257
267
  Thread.new do
@@ -264,14 +274,13 @@ module Taskinator
264
274
  end
265
275
 
266
276
  def task_completed(task)
267
- # deincrement the count of pending concurrent tasks
277
+ # decrement the count of pending concurrent tasks
268
278
  pending = deincr_pending_tasks
269
279
 
270
- Taskinator.statsd_client.count("taskinator.#{definition.name.underscore.parameterize}.pending", pending)
271
280
  Taskinator.logger.info("Completed task for process '#{uuid}'. Pending is #{pending}.")
272
281
 
273
282
  # when complete on first, then don't bother with subsequent tasks completing
274
- if (complete_on == CompleteOn::First)
283
+ if complete_on == CompleteOn::First
275
284
  complete! unless completed?
276
285
  else
277
286
  complete! if pending < 1
@@ -279,7 +288,7 @@ module Taskinator
279
288
  end
280
289
 
281
290
  def tasks_completed?
282
- if (complete_on == CompleteOn::First)
291
+ if complete_on == CompleteOn::First
283
292
  tasks.any?(&:completed?)
284
293
  else
285
294
  super # all
@@ -18,12 +18,6 @@ module Taskinator
18
18
  .perform_later(definition.name, uuid, Taskinator::Persistence.serialize(args))
19
19
  end
20
20
 
21
- def enqueue_process(process)
22
- queue = process.queue || @config[:process_queue]
23
- ProcessWorker.set(:queue => queue)
24
- .perform_later(process.uuid)
25
- end
26
-
27
21
  def enqueue_task(task)
28
22
  queue = task.queue || @config[:task_queue]
29
23
  TaskWorker.set(:queue => queue)
@@ -36,12 +30,6 @@ module Taskinator
36
30
  end
37
31
  end
38
32
 
39
- class ProcessWorker < ApplicationJob
40
- def perform(process_uuid)
41
- Taskinator::ProcessWorker.new(process_uuid).perform
42
- end
43
- end
44
-
45
33
  class TaskWorker < ApplicationJob
46
34
  def perform(task_uuid)
47
35
  Taskinator::TaskWorker.new(task_uuid).perform
@@ -17,11 +17,6 @@ module Taskinator
17
17
  ::Delayed::Job.enqueue CreateProcessWorker.new(definition.name, uuid, Taskinator::Persistence.serialize(args)), :queue => queue
18
18
  end
19
19
 
20
- def enqueue_process(process)
21
- queue = process.queue || @config[:process_queue]
22
- ::Delayed::Job.enqueue ProcessWorker.new(process.uuid), :queue => queue
23
- end
24
-
25
20
  def enqueue_task(task)
26
21
  queue = task.queue || @config[:task_queue]
27
22
  ::Delayed::Job.enqueue TaskWorker.new(task.uuid), :queue => queue
@@ -33,12 +28,6 @@ module Taskinator
33
28
  end
34
29
  end
35
30
 
36
- ProcessWorker = Struct.new(:process_uuid) do
37
- def perform
38
- Taskinator::ProcessWorker.new(process_uuid).perform
39
- end
40
- end
41
-
42
31
  TaskWorker = Struct.new(:task_uuid) do
43
32
  def perform
44
33
  Taskinator::TaskWorker.new(task_uuid).perform
@@ -15,10 +15,6 @@ module Taskinator
15
15
  @queue = config[:definition_queue]
16
16
  end
17
17
 
18
- ProcessWorker.class_eval do
19
- @queue = config[:process_queue]
20
- end
21
-
22
18
  TaskWorker.class_eval do
23
19
  @queue = config[:task_queue]
24
20
  end
@@ -30,11 +26,6 @@ module Taskinator
30
26
  Resque.enqueue_to(queue, CreateProcessWorker, definition.name, uuid, Taskinator::Persistence.serialize(args))
31
27
  end
32
28
 
33
- def enqueue_process(process)
34
- queue = process.queue || Resque.queue_from_class(ProcessWorker)
35
- Resque.enqueue_to(queue, ProcessWorker, process.uuid)
36
- end
37
-
38
29
  def enqueue_task(task)
39
30
  queue = task.queue || Resque.queue_from_class(TaskWorker)
40
31
  Resque.enqueue_to(queue, TaskWorker, task.uuid)
@@ -46,12 +37,6 @@ module Taskinator
46
37
  end
47
38
  end
48
39
 
49
- class ProcessWorker
50
- def self.perform(process_uuid)
51
- Taskinator::ProcessWorker.new(process_uuid).perform
52
- end
53
- end
54
-
55
40
  class TaskWorker
56
41
  def self.perform(task_uuid)
57
42
  Taskinator::TaskWorker.new(task_uuid).perform
@@ -17,11 +17,6 @@ module Taskinator
17
17
  CreateProcessWorker.client_push('class' => CreateProcessWorker, 'args' => [definition.name, uuid, Taskinator::Persistence.serialize(args)], 'queue' => queue)
18
18
  end
19
19
 
20
- def enqueue_process(process)
21
- queue = process.queue || @config[:process_queue]
22
- TaskWorker.client_push('class' => ProcessWorker, 'args' => [process.uuid], 'queue' => queue)
23
- end
24
-
25
20
  def enqueue_task(task)
26
21
  queue = task.queue || @config[:task_queue]
27
22
  TaskWorker.client_push('class' => TaskWorker, 'args' => [task.uuid], 'queue' => queue)
@@ -35,14 +30,6 @@ module Taskinator
35
30
  end
36
31
  end
37
32
 
38
- class ProcessWorker
39
- include ::Sidekiq::Worker
40
-
41
- def perform(process_uuid)
42
- Taskinator::ProcessWorker.new(process_uuid).perform
43
- end
44
- end
45
-
46
33
  class TaskWorker
47
34
  include ::Sidekiq::Worker
48
35
 
@@ -33,11 +33,6 @@ module Taskinator
33
33
  adapter.enqueue_create_process(definition, uuid, args)
34
34
  end
35
35
 
36
- def enqueue_process(process)
37
- Taskinator.logger.info("Enqueuing process #{process}")
38
- adapter.enqueue_process(process)
39
- end
40
-
41
36
  def enqueue_task(task)
42
37
  Taskinator.logger.info("Enqueuing task #{task}")
43
38
  adapter.enqueue_task(task)
@@ -21,6 +21,7 @@ module Taskinator
21
21
  end
22
22
 
23
23
  attr_reader :process
24
+ attr_reader :definition
24
25
  attr_reader :uuid
25
26
  attr_reader :options
26
27
  attr_reader :queue
@@ -35,6 +36,7 @@ module Taskinator
35
36
 
36
37
  @uuid = "#{process.uuid}:task:#{Taskinator.generate_uuid}"
37
38
  @process = process
39
+ @definition = process.definition
38
40
  @options = options
39
41
  @queue = options.delete(:queue)
40
42
  @created_at = Time.now.utc
@@ -45,6 +47,7 @@ module Taskinator
45
47
  def accept(visitor)
46
48
  visitor.visit_attribute(:uuid)
47
49
  visitor.visit_process_reference(:process)
50
+ visitor.visit_type(:definition)
48
51
  visitor.visit_task_reference(:next)
49
52
  visitor.visit_args(:options)
50
53
  visitor.visit_attribute(:queue)
@@ -134,6 +137,7 @@ module Taskinator
134
137
  # subclasses must implement the following methods
135
138
  #--------------------------------------------------
136
139
 
140
+ # :nocov:
137
141
  def enqueue
138
142
  raise NotImplementedError
139
143
  end
@@ -141,6 +145,7 @@ module Taskinator
141
145
  def start
142
146
  raise NotImplementedError
143
147
  end
148
+ # :nocov:
144
149
 
145
150
  #--------------------------------------------------
146
151
  # and optionally, provide methods:
@@ -155,13 +160,11 @@ module Taskinator
155
160
  # a task which invokes the specified method on the definition
156
161
  # the args must be intrinsic types, since they are serialized to YAML
157
162
  class Step < Task
158
- attr_reader :definition
159
163
  attr_reader :method
160
164
  attr_reader :args
161
165
 
162
166
  def initialize(process, method, args, options={})
163
167
  super(process, options)
164
- @definition = process.definition # for convenience
165
168
 
166
169
  raise ArgumentError, 'method' if method.nil?
167
170
  raise NoMethodError, method unless executor.respond_to?(method)
@@ -188,17 +191,16 @@ module Taskinator
188
191
 
189
192
  def accept(visitor)
190
193
  super
191
- visitor.visit_type(:definition)
192
194
  visitor.visit_attribute(:method)
193
195
  visitor.visit_args(:args)
194
196
  end
195
197
 
196
198
  def executor
197
- @executor ||= Taskinator::Executor.new(@definition, self)
199
+ @executor ||= Taskinator::Executor.new(definition, self)
198
200
  end
199
201
 
200
202
  def inspect
201
- %(#<#{self.class.name}:0x#{self.__id__.to_s(16)} uuid="#{uuid}", method=:#{method}, args=#{args}, current_state=:#{current_state}>)
203
+ %(#<#{self.class.name}:0x#{self.__id__.to_s(16)} uuid="#{uuid}", definition=:#{definition}, method=:#{method}, args=#{args}, current_state=:#{current_state}>)
202
204
  end
203
205
  end
204
206
 
@@ -207,13 +209,11 @@ module Taskinator
207
209
  # a task which invokes the specified background job
208
210
  # the args must be intrinsic types, since they are serialized to YAML
209
211
  class Job < Task
210
- attr_reader :definition
211
212
  attr_reader :job
212
213
  attr_reader :args
213
214
 
214
215
  def initialize(process, job, args, options={})
215
216
  super(process, options)
216
- @definition = process.definition # for convenience
217
217
 
218
218
  raise ArgumentError, 'job' if job.nil?
219
219
  raise ArgumentError, 'job' unless job.methods.include?(:perform) || job.instance_methods.include?(:perform)
@@ -228,7 +228,6 @@ module Taskinator
228
228
 
229
229
  def start
230
230
  # NNB: if other job types are required, may need to implement how they get invoked here!
231
- # FIXME: possible implement using ActiveJob instead, so it doesn't matter how the worker is implemented
232
231
 
233
232
  if job.respond_to?(:perform)
234
233
  # resque
@@ -250,13 +249,12 @@ module Taskinator
250
249
 
251
250
  def accept(visitor)
252
251
  super
253
- visitor.visit_type(:definition)
254
252
  visitor.visit_type(:job)
255
253
  visitor.visit_args(:args)
256
254
  end
257
255
 
258
256
  def inspect
259
- %(#<#{self.class.name}:0x#{self.__id__.to_s(16)} uuid="#{uuid}", job=#{job}, args=#{args}, current_state=:#{current_state}>)
257
+ %(#<#{self.class.name}:0x#{self.__id__.to_s(16)} uuid="#{uuid}", definition=:#{definition}, job=#{job}, args=#{args}, current_state=:#{current_state}>)
260
258
  end
261
259
  end
262
260
 
@@ -302,7 +300,7 @@ module Taskinator
302
300
  end
303
301
 
304
302
  def inspect
305
- %(#<#{self.class.name}:0x#{self.__id__.to_s(16)} uuid="#{uuid}", sub_process=#{sub_process.inspect}, current_state=:#{current_state}>)
303
+ %(#<#{self.class.name}:0x#{self.__id__.to_s(16)} uuid="#{uuid}", definition=:#{definition}, sub_process=#{sub_process.inspect}, current_state=:#{current_state}>)
306
304
  end
307
305
  end
308
306
  end
@@ -1,3 +1,3 @@
1
1
  module Taskinator
2
- VERSION = "0.4.7"
2
+ VERSION = "0.5.1"
3
3
  end
data/lib/taskinator.rb CHANGED
@@ -6,8 +6,6 @@ require 'delegate'
6
6
 
7
7
  require 'taskinator/version'
8
8
 
9
- require 'taskinator/log_stats'
10
-
11
9
  require 'taskinator/complete_on'
12
10
  require 'taskinator/redis_connection'
13
11
  require 'taskinator/logger'
@@ -19,14 +17,12 @@ require 'taskinator/workflow'
19
17
  require 'taskinator/visitor'
20
18
  require 'taskinator/persistence'
21
19
  require 'taskinator/instrumentation'
22
- require 'taskinator/xml_visitor'
23
20
 
24
21
  require 'taskinator/task'
25
22
  require 'taskinator/tasks'
26
23
  require 'taskinator/process'
27
24
 
28
25
  require 'taskinator/task_worker'
29
- require 'taskinator/process_worker'
30
26
  require 'taskinator/create_process_worker'
31
27
 
32
28
  require 'taskinator/executor'
@@ -88,14 +84,6 @@ module Taskinator
88
84
  Taskinator::Logging.logger = log
89
85
  end
90
86
 
91
- def statsd_client
92
- Taskinator::LogStats.client
93
- end
94
-
95
- def statsd_client=(client)
96
- Taskinator::LogStats.client = client
97
- end
98
-
99
87
  # the queue adapter to use
100
88
  # supported adapters include
101
89
  # :active_job, :delayed_job, :redis and :sidekiq
@@ -136,14 +124,12 @@ module Taskinator
136
124
  end
137
125
 
138
126
  class NoOpInstrumenter
139
- # :nocov:
140
127
  def instrument(event, payload={})
141
128
  yield(payload) if block_given?
142
129
  end
143
130
  end
144
131
 
145
132
  class ConsoleInstrumenter
146
- # :nocov:
147
133
  def instrument(event, payload={})
148
134
  puts [event.inspect, payload.to_yaml]
149
135
  yield(payload) if block_given?
@@ -0,0 +1,30 @@
1
+ module TestJob
2
+ def self.perform(*args)
3
+ end
4
+ end
5
+
6
+ class TestJobClass
7
+ def perform(*args)
8
+ end
9
+ end
10
+
11
+ module TestJobModule
12
+ def self.perform(*args)
13
+ end
14
+ end
15
+
16
+ class TestJobClassNoArgs
17
+ def perform
18
+ end
19
+ end
20
+
21
+ module TestJobModuleNoArgs
22
+ def self.perform
23
+ end
24
+ end
25
+
26
+ module TestJobError
27
+ def self.perform
28
+ raise ArgumentError
29
+ end
30
+ end
@@ -0,0 +1,2 @@
1
+ class TestJobTask < Taskinator::Task::Job
2
+ end
@@ -2,38 +2,42 @@ module Taskinator
2
2
  module Queues
3
3
 
4
4
  def self.create_test_queue_adapter(config={})
5
- TestQueueAdapter.new
5
+ TestQueueAdapter.new(config)
6
6
  end
7
7
 
8
8
  def self.create_test_queue_worker_adapter(config={})
9
- QueueWorkerAdapter.new
9
+ TestQueueWorkerAdapter.new(config)
10
10
  end
11
11
 
12
+ #
13
+ # this is a no-op adapter, it tracks enqueued processes and tasks
14
+ #
12
15
  class TestQueueAdapter
13
16
 
14
- attr_reader :creates
15
- attr_reader :tasks
16
-
17
- def initialize
17
+ def initialize(config={})
18
18
  clear
19
19
  end
20
20
 
21
- def clear
22
- @creates = []
23
- @tasks = []
24
- @jobs = []
25
- end
26
-
27
21
  def enqueue_create_process(definition, uuid, args)
28
- @creates << [definition, uuid, args]
22
+ @processes << [definition, uuid, args]
29
23
  end
30
24
 
31
25
  def enqueue_task(task)
32
26
  @tasks << task
33
27
  end
34
28
 
29
+ # helpers
30
+
31
+ attr_reader :processes
32
+ attr_reader :tasks
33
+
34
+ def clear
35
+ @processes = []
36
+ @tasks = []
37
+ end
38
+
35
39
  def empty?
36
- @creates.empty? && @tasks.empty? && @jobs.empty?
40
+ @processes.empty? && @tasks.empty?
37
41
  end
38
42
 
39
43
  end
@@ -41,7 +45,7 @@ module Taskinator
41
45
  #
42
46
  # this is a "synchronous" implementation for use in testing
43
47
  #
44
- class QueueWorkerAdapter < TestQueueAdapter
48
+ class TestQueueWorkerAdapter < TestQueueAdapter
45
49
 
46
50
  def enqueue_create_process(definition, uuid, args)
47
51
  super
@@ -57,6 +61,8 @@ module Taskinator
57
61
  end
58
62
  end
59
63
 
64
+ private
65
+
60
66
  def invoke(&block)
61
67
  block.call
62
68
  end
@@ -0,0 +1,2 @@
1
+ class TestStepTask < Taskinator::Task::Step
2
+ end
@@ -0,0 +1,2 @@
1
+ class TestSubProcessTask < Taskinator::Task::SubProcess
2
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Taskinator::Definition::Builder do
3
+ describe Taskinator::Builder do
4
4
 
5
5
  let(:definition) do
6
6
  Module.new do
@@ -26,7 +26,7 @@ describe Taskinator::Definition::Builder do
26
26
  Proc.new {|*args| the_block.call }
27
27
  }
28
28
 
29
- subject { Taskinator::Definition::Builder.new(process, definition, *[*args, builder_options]) }
29
+ subject { Taskinator::Builder.new(process, definition, *[*args, builder_options]) }
30
30
 
31
31
  it "assign attributes" do
32
32
  expect(subject.process).to eq(process)