taskinator 0.4.7 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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)