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
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.4.7
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Stefano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-17 00:00:00.000000000 Z
11
+ date: 2023-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -84,42 +84,28 @@ dependencies:
84
84
  name: globalid
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0.3'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.3'
97
- - !ruby/object:Gem::Dependency
98
- name: statsd-ruby
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: 1.4.0
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: 1.4.0
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: thwait
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
- - - "~>"
101
+ - - ">="
116
102
  - !ruby/object:Gem::Version
117
103
  version: '0.2'
118
104
  type: :runtime
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
107
  requirements:
122
- - - "~>"
108
+ - - ">="
123
109
  - !ruby/object:Gem::Version
124
110
  version: '0.2'
125
111
  description: Simple process orchestration
@@ -134,7 +120,8 @@ files:
134
120
  - ".github/ISSUE_TEMPLATE/bug_report.md"
135
121
  - ".github/ISSUE_TEMPLATE/custom.md"
136
122
  - ".github/ISSUE_TEMPLATE/feature_request.md"
137
- - ".github/workflows/taskinator.yml"
123
+ - ".github/workflows/build.yml"
124
+ - ".github/workflows/release.yml"
138
125
  - ".gitignore"
139
126
  - ".rspec"
140
127
  - ".ruby-gemset"
@@ -151,17 +138,15 @@ files:
151
138
  - bin/setup
152
139
  - lib/taskinator.rb
153
140
  - lib/taskinator/api.rb
141
+ - lib/taskinator/builder.rb
154
142
  - lib/taskinator/complete_on.rb
155
143
  - lib/taskinator/create_process_worker.rb
156
144
  - lib/taskinator/definition.rb
157
- - lib/taskinator/definition/builder.rb
158
145
  - lib/taskinator/executor.rb
159
146
  - lib/taskinator/instrumentation.rb
160
- - lib/taskinator/log_stats.rb
161
147
  - lib/taskinator/logger.rb
162
148
  - lib/taskinator/persistence.rb
163
149
  - lib/taskinator/process.rb
164
- - lib/taskinator/process_worker.rb
165
150
  - lib/taskinator/queues.rb
166
151
  - lib/taskinator/queues/active_job.rb
167
152
  - lib/taskinator/queues/delayed_job.rb
@@ -174,7 +159,6 @@ files:
174
159
  - lib/taskinator/version.rb
175
160
  - lib/taskinator/visitor.rb
176
161
  - lib/taskinator/workflow.rb
177
- - lib/taskinator/xml_visitor.rb
178
162
  - processes_workflow.png
179
163
  - sequence.txt
180
164
  - spec/examples/process_examples.rb
@@ -192,23 +176,27 @@ files:
192
176
  - spec/support/test_flow.rb
193
177
  - spec/support/test_flows.rb
194
178
  - spec/support/test_instrumenter.rb
179
+ - spec/support/test_job.rb
180
+ - spec/support/test_job_task.rb
195
181
  - spec/support/test_process.rb
196
182
  - spec/support/test_queue.rb
183
+ - spec/support/test_step_task.rb
184
+ - spec/support/test_subprocess_task.rb
197
185
  - spec/support/test_task.rb
198
186
  - spec/taskinator/api_spec.rb
187
+ - spec/taskinator/builder_spec.rb
199
188
  - spec/taskinator/complex_process_spec.rb
200
189
  - spec/taskinator/create_process_worker_spec.rb
201
- - spec/taskinator/definition/builder_spec.rb
202
190
  - spec/taskinator/definition_spec.rb
203
191
  - spec/taskinator/executor_spec.rb
204
192
  - spec/taskinator/instrumentation_spec.rb
205
193
  - spec/taskinator/persistence_spec.rb
206
194
  - spec/taskinator/process_spec.rb
207
- - spec/taskinator/process_worker_spec.rb
208
195
  - spec/taskinator/queues/active_job_spec.rb
209
196
  - spec/taskinator/queues/delayed_job_spec.rb
210
197
  - spec/taskinator/queues/resque_spec.rb
211
198
  - spec/taskinator/queues/sidekiq_spec.rb
199
+ - spec/taskinator/queues/test_queue_adapter_spec.rb
212
200
  - spec/taskinator/queues_spec.rb
213
201
  - spec/taskinator/task_spec.rb
214
202
  - spec/taskinator/task_worker_spec.rb
@@ -216,7 +204,6 @@ files:
216
204
  - spec/taskinator/tasks_spec.rb
217
205
  - spec/taskinator/test_flows_spec.rb
218
206
  - spec/taskinator/visitor_spec.rb
219
- - spec/taskinator/xml_visitor_spec.rb
220
207
  - taskinator.gemspec
221
208
  - tasks_workflow.png
222
209
  homepage: https://github.com/virtualstaticvoid/taskinator
@@ -259,23 +246,27 @@ test_files:
259
246
  - spec/support/test_flow.rb
260
247
  - spec/support/test_flows.rb
261
248
  - spec/support/test_instrumenter.rb
249
+ - spec/support/test_job.rb
250
+ - spec/support/test_job_task.rb
262
251
  - spec/support/test_process.rb
263
252
  - spec/support/test_queue.rb
253
+ - spec/support/test_step_task.rb
254
+ - spec/support/test_subprocess_task.rb
264
255
  - spec/support/test_task.rb
265
256
  - spec/taskinator/api_spec.rb
257
+ - spec/taskinator/builder_spec.rb
266
258
  - spec/taskinator/complex_process_spec.rb
267
259
  - spec/taskinator/create_process_worker_spec.rb
268
- - spec/taskinator/definition/builder_spec.rb
269
260
  - spec/taskinator/definition_spec.rb
270
261
  - spec/taskinator/executor_spec.rb
271
262
  - spec/taskinator/instrumentation_spec.rb
272
263
  - spec/taskinator/persistence_spec.rb
273
264
  - spec/taskinator/process_spec.rb
274
- - spec/taskinator/process_worker_spec.rb
275
265
  - spec/taskinator/queues/active_job_spec.rb
276
266
  - spec/taskinator/queues/delayed_job_spec.rb
277
267
  - spec/taskinator/queues/resque_spec.rb
278
268
  - spec/taskinator/queues/sidekiq_spec.rb
269
+ - spec/taskinator/queues/test_queue_adapter_spec.rb
279
270
  - spec/taskinator/queues_spec.rb
280
271
  - spec/taskinator/task_spec.rb
281
272
  - spec/taskinator/task_worker_spec.rb
@@ -283,4 +274,3 @@ test_files:
283
274
  - spec/taskinator/tasks_spec.rb
284
275
  - spec/taskinator/test_flows_spec.rb
285
276
  - spec/taskinator/visitor_spec.rb
286
- - spec/taskinator/xml_visitor_spec.rb
@@ -1,129 +0,0 @@
1
- module Taskinator
2
- module Definition
3
- class Builder
4
-
5
- attr_reader :process
6
- attr_reader :definition
7
- attr_reader :args
8
- attr_reader :builder_options
9
-
10
- def initialize(process, definition, *args)
11
- @process = process
12
- @definition = definition
13
- @builder_options = args.last.is_a?(Hash) ? args.pop : {}
14
- @args = args
15
- @executor = Taskinator::Executor.new(@definition)
16
- end
17
-
18
- def option?(key, &block)
19
- yield if builder_options[key]
20
- end
21
-
22
- # defines a sub process of tasks which are executed sequentially
23
- def sequential(options={}, &block)
24
- raise ArgumentError, 'block' unless block_given?
25
-
26
- sub_process = Process.define_sequential_process_for(@definition, options)
27
- task = define_sub_process_task(@process, sub_process, options)
28
- Builder.new(sub_process, @definition, *@args).instance_eval(&block)
29
- @process.tasks << task if sub_process.tasks.any?
30
- nil
31
- end
32
-
33
- # defines a sub process of tasks which are executed concurrently
34
- def concurrent(complete_on=CompleteOn::Default, options={}, &block)
35
- raise ArgumentError, 'block' unless block_given?
36
-
37
- sub_process = Process.define_concurrent_process_for(@definition, complete_on, options)
38
- task = define_sub_process_task(@process, sub_process, options)
39
- Builder.new(sub_process, @definition, *@args).instance_eval(&block)
40
- @process.tasks << task if sub_process.tasks.any?
41
- nil
42
- end
43
-
44
- # dynamically defines tasks, using the given @iterator method
45
- # the definition will be evaluated for each yielded item
46
- def for_each(method, options={}, &block)
47
- raise ArgumentError, 'method' if method.nil?
48
- raise NoMethodError, method unless @executor.respond_to?(method)
49
- raise ArgumentError, 'block' unless block_given?
50
-
51
- #
52
- # `for_each` is an exception, since it invokes the definition
53
- # in order to yield elements to the builder, and any options passed
54
- # are included with the builder options
55
- #
56
- method_args = options.any? ? [*@args, options] : @args
57
- @executor.send(method, *method_args) do |*args|
58
- Builder.new(@process, @definition, *args).instance_eval(&block)
59
- end
60
- nil
61
- end
62
-
63
- alias_method :transform, :for_each
64
-
65
- # defines a task which executes the given @method
66
- def task(method, options={})
67
- raise ArgumentError, 'method' if method.nil?
68
- raise NoMethodError, method unless @executor.respond_to?(method)
69
-
70
- define_step_task(@process, method, @args, options)
71
- nil
72
- end
73
-
74
- # defines a task which executes the given @job
75
- # which is expected to implement a perform method either as a class or instance method
76
- def job(job, options={})
77
- raise ArgumentError, 'job' if job.nil?
78
- raise ArgumentError, 'job' unless job.methods.include?(:perform) || job.instance_methods.include?(:perform)
79
-
80
- define_job_task(@process, job, @args, options)
81
- nil
82
- end
83
-
84
- # defines a sub process task, for the given @definition
85
- # the definition specified must have input compatible arguments
86
- # to the current definition
87
- def sub_process(definition, options={})
88
- raise ArgumentError, 'definition' if definition.nil?
89
- raise ArgumentError, "#{definition.name} does not extend the #{Definition.name} module" unless definition.kind_of?(Definition)
90
-
91
- # TODO: decide whether the sub process to dynamically receive arguments
92
-
93
- sub_process = definition.create_sub_process(*@args, combine_options(options))
94
- task = define_sub_process_task(@process, sub_process, options)
95
- Builder.new(sub_process, definition, *@args)
96
- @process.tasks << task if sub_process.tasks.any?
97
- nil
98
- end
99
-
100
- private
101
-
102
- def define_step_task(process, method, args, options={})
103
- define_task(process) {
104
- Task.define_step_task(process, method, args, combine_options(options))
105
- }
106
- end
107
-
108
- def define_job_task(process, job, args, options={})
109
- define_task(process) {
110
- Task.define_job_task(process, job, args, combine_options(options))
111
- }
112
- end
113
-
114
- def define_sub_process_task(process, sub_process, options={})
115
- Task.define_sub_process_task(process, sub_process, combine_options(options))
116
- end
117
-
118
- def define_task(process)
119
- process.tasks << task = yield
120
- task
121
- end
122
-
123
- def combine_options(options={})
124
- builder_options.merge(options)
125
- end
126
-
127
- end
128
- end
129
- end
@@ -1,49 +0,0 @@
1
- require 'statsd'
2
-
3
- module Taskinator
4
- module LogStats
5
- class << self
6
-
7
- def initialize_client
8
- @client = Statsd.new()
9
- end
10
-
11
- def client
12
- defined?(@client) ? @client : initialize_client
13
- end
14
-
15
- def client=(statsd_client)
16
- @client = (statsd_client ? statsd_client : initialize_client)
17
- end
18
-
19
- def duration(stat, duration)
20
- client.timing(stat, duration * 1000)
21
- end
22
-
23
- def timing(stat, &block)
24
- result = nil
25
- duration = Benchmark.realtime do
26
- result = yield
27
- end
28
- duration(stat, duration)
29
- result
30
- end
31
-
32
- def gauge(stat, count)
33
- client.gauge(stat, count)
34
- end
35
-
36
- def count(stat, count)
37
- client.count(stat, count)
38
- end
39
-
40
- def increment(stat)
41
- client.increment(stat)
42
- end
43
-
44
- def decrement(stat)
45
- client.decrement(stat)
46
- end
47
- end
48
- end
49
- end
@@ -1,13 +0,0 @@
1
- module Taskinator
2
- class ProcessWorker
3
- attr_reader :uuid
4
-
5
- def initialize(uuid)
6
- @uuid = uuid
7
- end
8
-
9
- def perform
10
- # TODO: build the process, and enqueue it. after it completes, report back to the containing process
11
- end
12
- end
13
- end
@@ -1,109 +0,0 @@
1
- require 'builder'
2
-
3
- module Taskinator
4
- module Visitor
5
- class XmlVisitor
6
- class << self
7
- def to_xml(process)
8
- builder = ::Builder::XmlMarkup.new(:indent => 2)
9
- builder.instruct!
10
- builder.tag!('process') do
11
- XmlVisitor.new(builder, process).visit
12
- end
13
- end
14
- end
15
-
16
- attr_reader :builder
17
- attr_reader :instance
18
-
19
- def initialize(builder, instance)
20
- @builder = builder
21
- @instance = instance
22
- end
23
-
24
- def visit
25
- @instance.accept(self)
26
- end
27
-
28
- def write_error(error)
29
- return unless error[0]
30
- builder.tag!('error', :type => error[0]) do
31
- builder.message(error[1])
32
- builder.cdata!(error[2].join("\n"))
33
- end
34
- end
35
-
36
- def visit_process(attribute)
37
- process = @instance.send(attribute)
38
- if process
39
- p = process.__getobj__
40
-
41
- attribs = {
42
- :type => p.class.name,
43
- :current_state => p.current_state
44
- }
45
-
46
- builder.tag!('process', attribs) do
47
- XmlVisitor.new(builder, p).visit
48
- write_error(p.error)
49
- end
50
- end
51
- end
52
-
53
- def visit_tasks(tasks)
54
- tasks.each do |task|
55
- t = task.__getobj__
56
-
57
- attribs = {
58
- :type => t.class.name,
59
- :current_state => t.current_state
60
- }
61
-
62
- builder.tag!('task', attribs) do
63
- XmlVisitor.new(builder, t).visit
64
- write_error(t.error)
65
- end
66
- end
67
- end
68
-
69
- def visit_attribute(attribute)
70
- value = @instance.send(attribute)
71
- builder.tag!('attribute', :name => attribute, :value => value) if value
72
- end
73
-
74
- def visit_attribute_time(attribute)
75
- visit_attribute(attribute)
76
- end
77
-
78
- def visit_attribute_enum(attribute, type)
79
- visit_attribute(attribute)
80
- end
81
-
82
- def visit_process_reference(attribute)
83
- process = @instance.send(attribute)
84
- builder.tag!('attribute_ref', { :name => attribute, :type => process.__getobj__.class.name, :value => process.uuid }) if process
85
- end
86
-
87
- def visit_task_reference(attribute)
88
- task = @instance.send(attribute)
89
- builder.tag!('attribute_ref', { :name => attribute, :type => task.__getobj__.class.name, :value => task.uuid }) if task
90
- end
91
-
92
- def visit_type(attribute)
93
- type = @instance.send(attribute)
94
- builder.tag!('attribute', { :name => attribute, :value => type.name })
95
- end
96
-
97
- def visit_args(attribute)
98
- values = @instance.send(attribute)
99
-
100
- builder.tag!('attribute', :name => attribute) do
101
- builder.cdata!(values.to_json)
102
- end if values && !values.empty?
103
- end
104
-
105
- def task_count
106
- end
107
- end
108
- end
109
- end
@@ -1,5 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Taskinator::ProcessWorker do
4
- pending
5
- end
@@ -1,5 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Taskinator::Visitor::XmlVisitor do
4
- pending
5
- end