taskinator 0.0.3 → 0.0.4
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 +4 -4
- data/Gemfile.lock +16 -16
- data/lib/taskinator/definition/builder.rb +15 -0
- data/lib/taskinator/job_worker.rb +20 -0
- data/lib/taskinator/persistence.rb +38 -6
- data/lib/taskinator/queues/delayed_job.rb +15 -1
- data/lib/taskinator/queues/resque.rb +22 -1
- data/lib/taskinator/queues/sidekiq.rb +24 -1
- data/lib/taskinator/task.rb +35 -1
- data/lib/taskinator/version.rb +1 -1
- data/lib/taskinator.rb +1 -0
- data/spec/support/test_flow.rb +10 -0
- data/spec/taskinator/definition/builder_spec.rb +22 -1
- data/spec/taskinator/job_worker_spec.rb +71 -0
- data/spec/taskinator/queues/delayed_job_spec.rb +61 -18
- data/spec/taskinator/queues/resque_spec.rb +55 -16
- data/spec/taskinator/queues/sidekiq_spec.rb +61 -18
- data/spec/taskinator/task_spec.rb +45 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ae6a63807d0e3e2cb0c513f348eeab155abe830
|
4
|
+
data.tar.gz: ce5a3c1168ff6a3d1bcb623452c458dac6b96dee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5da9ab4636b65d268ed99c45679433c37fe6c7097c7af6c26bbc8a03e08362f3ac6709da209c43950428a6f2b43b1df3a37242e4f28602ca378ec6d40f9063cf
|
7
|
+
data.tar.gz: d538da07fdd101f86077ad08d2415fc87fab6df2d89327c6df530b56b4f93deaee633095d0fec1633cfc55ae50faa64fb7697614920dcd83bee24a8e33a6b8d3
|
data/Gemfile.lock
CHANGED
@@ -8,7 +8,7 @@ GIT
|
|
8
8
|
PATH
|
9
9
|
remote: .
|
10
10
|
specs:
|
11
|
-
taskinator (0.0.
|
11
|
+
taskinator (0.0.4)
|
12
12
|
connection_pool (>= 2.0.0)
|
13
13
|
json (>= 1.8.1)
|
14
14
|
redis (>= 3.0.6)
|
@@ -17,7 +17,7 @@ PATH
|
|
17
17
|
GEM
|
18
18
|
remote: https://rubygems.org/
|
19
19
|
specs:
|
20
|
-
activesupport (4.1.
|
20
|
+
activesupport (4.1.6)
|
21
21
|
i18n (~> 0.6, >= 0.6.9)
|
22
22
|
json (~> 1.7, >= 1.7.7)
|
23
23
|
minitest (~> 5.1)
|
@@ -38,7 +38,7 @@ GEM
|
|
38
38
|
term-ansicolor
|
39
39
|
thor
|
40
40
|
debugger-linecache (1.2.0)
|
41
|
-
delayed_job (4.0.
|
41
|
+
delayed_job (4.0.3)
|
42
42
|
activesupport (>= 3.0, < 4.2)
|
43
43
|
diff-lcs (1.2.5)
|
44
44
|
docile (1.1.5)
|
@@ -78,20 +78,20 @@ GEM
|
|
78
78
|
rest-client (1.7.2)
|
79
79
|
mime-types (>= 1.16, < 3.0)
|
80
80
|
netrc (~> 0.7)
|
81
|
-
rspec (3.
|
82
|
-
rspec-core (~> 3.
|
83
|
-
rspec-expectations (~> 3.
|
84
|
-
rspec-mocks (~> 3.
|
85
|
-
rspec-core (3.
|
86
|
-
rspec-support (~> 3.
|
87
|
-
rspec-expectations (3.0
|
81
|
+
rspec (3.1.0)
|
82
|
+
rspec-core (~> 3.1.0)
|
83
|
+
rspec-expectations (~> 3.1.0)
|
84
|
+
rspec-mocks (~> 3.1.0)
|
85
|
+
rspec-core (3.1.2)
|
86
|
+
rspec-support (~> 3.1.0)
|
87
|
+
rspec-expectations (3.1.0)
|
88
88
|
diff-lcs (>= 1.2.0, < 2.0)
|
89
|
-
rspec-support (~> 3.
|
90
|
-
rspec-mocks (3.0
|
91
|
-
rspec-support (~> 3.
|
92
|
-
rspec-support (3.0
|
93
|
-
sidekiq (3.2.
|
94
|
-
celluloid (
|
89
|
+
rspec-support (~> 3.1.0)
|
90
|
+
rspec-mocks (3.1.0)
|
91
|
+
rspec-support (~> 3.1.0)
|
92
|
+
rspec-support (3.1.0)
|
93
|
+
sidekiq (3.2.5)
|
94
|
+
celluloid (= 0.15.2)
|
95
95
|
connection_pool (>= 2.0.0)
|
96
96
|
json
|
97
97
|
redis (>= 3.0.6)
|
@@ -49,6 +49,15 @@ module Taskinator
|
|
49
49
|
define_step_task(@process, method, @args, options)
|
50
50
|
end
|
51
51
|
|
52
|
+
# defines a task which executes the given @job
|
53
|
+
# which is expected to implement a perform method either as a class or instance method
|
54
|
+
def job(job, options={})
|
55
|
+
raise ArgumentError, 'job' if job.nil?
|
56
|
+
raise ArgumentError, 'job' unless job.methods.include?(:perform) || job.instance_methods.include?(:perform)
|
57
|
+
|
58
|
+
define_job_task(@process, job, @args, options)
|
59
|
+
end
|
60
|
+
|
52
61
|
# defines a sub process task, for the given @definition
|
53
62
|
# the definition specified must have input compatible arguments
|
54
63
|
# to the current definition
|
@@ -70,6 +79,12 @@ module Taskinator
|
|
70
79
|
}
|
71
80
|
end
|
72
81
|
|
82
|
+
def define_job_task(process, job, args, options={})
|
83
|
+
define_task(process) {
|
84
|
+
Task.define_job_task(process, job, args, options)
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
73
88
|
def define_sub_process_task(process, sub_process, options={})
|
74
89
|
define_task(process) {
|
75
90
|
Task.define_sub_process_task(process, sub_process, options)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Taskinator
|
2
|
+
class JobWorker
|
3
|
+
def initialize(uuid)
|
4
|
+
@uuid = uuid
|
5
|
+
end
|
6
|
+
|
7
|
+
# NB: must be provided a block for the implmentation of the job execution
|
8
|
+
def perform(&block)
|
9
|
+
task = Taskinator::Task.fetch(@uuid)
|
10
|
+
return if task.paused? || task.cancelled?
|
11
|
+
begin
|
12
|
+
task.start!
|
13
|
+
task.perform &block
|
14
|
+
task.complete!
|
15
|
+
rescue Exception => e
|
16
|
+
task.fail!(e)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -168,8 +168,24 @@ module Taskinator
|
|
168
168
|
end
|
169
169
|
|
170
170
|
def visit_args(attribute)
|
171
|
-
|
172
|
-
|
171
|
+
values = @instance.send(attribute)
|
172
|
+
|
173
|
+
# special case, convert models to global id's
|
174
|
+
if values.is_a?(Array)
|
175
|
+
|
176
|
+
values = values.collect {|value|
|
177
|
+
value.respond_to?(:global_id) ? value.global_id : value
|
178
|
+
}
|
179
|
+
|
180
|
+
elsif values.is_a?(Hash)
|
181
|
+
|
182
|
+
values.each {|key, value|
|
183
|
+
values[key] = value.global_id if value.respond_to?(:global_id)
|
184
|
+
}
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
@hmset += [attribute, YAML.dump(values)]
|
173
189
|
end
|
174
190
|
end
|
175
191
|
|
@@ -258,10 +274,26 @@ module Taskinator
|
|
258
274
|
|
259
275
|
# deserializes the arguments using YAML#load method
|
260
276
|
def visit_args(attribute)
|
261
|
-
|
262
|
-
if
|
263
|
-
|
264
|
-
|
277
|
+
yaml = @attribute_values[attribute]
|
278
|
+
if yaml
|
279
|
+
values = YAML.load(yaml)
|
280
|
+
|
281
|
+
# special case for models, so find model
|
282
|
+
if values.is_a?(Array)
|
283
|
+
|
284
|
+
values = values.collect {|value|
|
285
|
+
value.respond_to?(:find) ? value.find : value
|
286
|
+
}
|
287
|
+
|
288
|
+
elsif values.is_a?(Hash)
|
289
|
+
|
290
|
+
values.each {|key, value|
|
291
|
+
values[key] = value.find if value.respond_to?(:find)
|
292
|
+
}
|
293
|
+
|
294
|
+
end
|
295
|
+
|
296
|
+
@instance.instance_variable_set("@#{attribute}", values)
|
265
297
|
end
|
266
298
|
end
|
267
299
|
|
@@ -11,7 +11,8 @@ module Taskinator
|
|
11
11
|
def initialize(config={})
|
12
12
|
@config = {
|
13
13
|
:process_queue => :default,
|
14
|
-
:task_queue => :default
|
14
|
+
:task_queue => :default,
|
15
|
+
:job_queue => :default,
|
15
16
|
}.merge(config)
|
16
17
|
end
|
17
18
|
|
@@ -23,6 +24,11 @@ module Taskinator
|
|
23
24
|
::Delayed::Job.enqueue TaskWorker.new(task.uuid), :queue => @config[:task_queue]
|
24
25
|
end
|
25
26
|
|
27
|
+
def enqueue_job(job)
|
28
|
+
# delayed jobs don't define the queue so use the configured queue instead
|
29
|
+
::Delayed::Job.enqueue JobWorker.new(job.uuid), :queue => @config[:job_queue]
|
30
|
+
end
|
31
|
+
|
26
32
|
ProcessWorker = Struct.new(:process_uuid) do
|
27
33
|
def perform
|
28
34
|
Taskinator::ProcessWorker.new(process_uuid).perform
|
@@ -34,6 +40,14 @@ module Taskinator
|
|
34
40
|
Taskinator::TaskWorker.new(task_uuid).perform
|
35
41
|
end
|
36
42
|
end
|
43
|
+
|
44
|
+
JobWorker = Struct.new(:job_uuid) do
|
45
|
+
def perform
|
46
|
+
Taskinator::JobWorker.new(job_uuid).perform do |job, args|
|
47
|
+
job.new(*args).perform
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
37
51
|
end
|
38
52
|
end
|
39
53
|
end
|
@@ -11,7 +11,8 @@ module Taskinator
|
|
11
11
|
def initialize(config={})
|
12
12
|
config = {
|
13
13
|
:process_queue => :default,
|
14
|
-
:task_queue => :default
|
14
|
+
:task_queue => :default,
|
15
|
+
:job_queue => :default
|
15
16
|
}.merge(config)
|
16
17
|
|
17
18
|
ProcessWorker.class_eval do
|
@@ -21,6 +22,10 @@ module Taskinator
|
|
21
22
|
TaskWorker.class_eval do
|
22
23
|
@queue = config[:task_queue]
|
23
24
|
end
|
25
|
+
|
26
|
+
JobWorker.class_eval do
|
27
|
+
@queue = config[:job_queue]
|
28
|
+
end
|
24
29
|
end
|
25
30
|
|
26
31
|
def enqueue_process(process)
|
@@ -31,6 +36,14 @@ module Taskinator
|
|
31
36
|
Resque.enqueue(TaskWorker, task.uuid)
|
32
37
|
end
|
33
38
|
|
39
|
+
def enqueue_job(job)
|
40
|
+
# get the queue name
|
41
|
+
queue = Resque.queue_from_class(job.job) ||
|
42
|
+
Resque.queue_from_class(JobWorker)
|
43
|
+
|
44
|
+
Resque.enqueue_to(queue, JobWorker, job.uuid)
|
45
|
+
end
|
46
|
+
|
34
47
|
class ProcessWorker
|
35
48
|
def self.perform(process_uuid)
|
36
49
|
Taskinator::ProcessWorker.new(process_uuid).perform
|
@@ -42,6 +55,14 @@ module Taskinator
|
|
42
55
|
Taskinator::TaskWorker.new(task_uuid).perform
|
43
56
|
end
|
44
57
|
end
|
58
|
+
|
59
|
+
class JobWorker
|
60
|
+
def self.perform(job_uuid)
|
61
|
+
Taskinator::JobWorker.new(job_uuid).perform do |job, args|
|
62
|
+
job.perform(*args)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
45
66
|
end
|
46
67
|
end
|
47
68
|
end
|
@@ -11,7 +11,8 @@ module Taskinator
|
|
11
11
|
def initialize(config={})
|
12
12
|
config = {
|
13
13
|
:process_queue => :default,
|
14
|
-
:task_queue => :default
|
14
|
+
:task_queue => :default,
|
15
|
+
:job_queue => :default
|
15
16
|
}.merge(config)
|
16
17
|
|
17
18
|
ProcessWorker.class_eval do
|
@@ -21,6 +22,10 @@ module Taskinator
|
|
21
22
|
TaskWorker.class_eval do
|
22
23
|
sidekiq_options :queue => config[:task_queue]
|
23
24
|
end
|
25
|
+
|
26
|
+
JobWorker.class_eval do
|
27
|
+
sidekiq_options :queue => config[:job_queue]
|
28
|
+
end
|
24
29
|
end
|
25
30
|
|
26
31
|
def enqueue_process(process)
|
@@ -31,6 +36,14 @@ module Taskinator
|
|
31
36
|
TaskWorker.perform_async(task.uuid)
|
32
37
|
end
|
33
38
|
|
39
|
+
def enqueue_job(job)
|
40
|
+
# get the queue name
|
41
|
+
queue = job.job.get_sidekiq_options['queue']
|
42
|
+
JobWorker.get_sidekiq_options.merge!('queue' => queue) if queue
|
43
|
+
|
44
|
+
JobWorker.perform_async(job.uuid)
|
45
|
+
end
|
46
|
+
|
34
47
|
class ProcessWorker
|
35
48
|
include ::Sidekiq::Worker
|
36
49
|
|
@@ -46,6 +59,16 @@ module Taskinator
|
|
46
59
|
Taskinator::TaskWorker.new(task_uuid).perform
|
47
60
|
end
|
48
61
|
end
|
62
|
+
|
63
|
+
class JobWorker
|
64
|
+
include ::Sidekiq::Worker
|
65
|
+
|
66
|
+
def perform(job_uuid)
|
67
|
+
Taskinator::JobWorker.new(job_uuid).perform do |job, args|
|
68
|
+
job.new.perform(*args)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
49
72
|
end
|
50
73
|
end
|
51
74
|
end
|
data/lib/taskinator/task.rb
CHANGED
@@ -8,6 +8,10 @@ module Taskinator
|
|
8
8
|
Step.new(process, method, args, options)
|
9
9
|
end
|
10
10
|
|
11
|
+
def define_job_task(process, job, args, options={})
|
12
|
+
Job.new(process, job, args, options)
|
13
|
+
end
|
14
|
+
|
11
15
|
def define_sub_process_task(process, sub_process, options={})
|
12
16
|
SubProcess.new(process, sub_process, options)
|
13
17
|
end
|
@@ -108,7 +112,7 @@ module Taskinator
|
|
108
112
|
end
|
109
113
|
|
110
114
|
# a task which invokes the specified method on the definition
|
111
|
-
# the args must be intrinsic types, since they are serialized to
|
115
|
+
# the args must be intrinsic types, since they are serialized to YAML
|
112
116
|
class Step < Task
|
113
117
|
attr_reader :definition
|
114
118
|
attr_reader :method
|
@@ -148,6 +152,36 @@ module Taskinator
|
|
148
152
|
end
|
149
153
|
end
|
150
154
|
|
155
|
+
# a task which invokes the specified background job
|
156
|
+
# the args must be intrinsic types, since they are serialized to YAML
|
157
|
+
class Job < Task
|
158
|
+
attr_reader :definition
|
159
|
+
attr_reader :job
|
160
|
+
attr_reader :args
|
161
|
+
|
162
|
+
def initialize(process, job, args, options={})
|
163
|
+
super(process, options)
|
164
|
+
@definition = process.definition # for convenience
|
165
|
+
|
166
|
+
raise ArgumentError, 'job' if job.nil?
|
167
|
+
raise ArgumentError, 'job' unless job.methods.include?(:perform) || job.instance_methods.include?(:perform)
|
168
|
+
|
169
|
+
@job = job
|
170
|
+
@args = args
|
171
|
+
end
|
172
|
+
|
173
|
+
def perform(&block)
|
174
|
+
yield(job, args)
|
175
|
+
end
|
176
|
+
|
177
|
+
def accept(visitor)
|
178
|
+
super
|
179
|
+
visitor.visit_type(:definition)
|
180
|
+
visitor.visit_type(:job)
|
181
|
+
visitor.visit_args(:args)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
151
185
|
# a task which delegates to another process
|
152
186
|
class SubProcess < Task
|
153
187
|
attr_reader :sub_process
|
data/lib/taskinator/version.rb
CHANGED
data/lib/taskinator.rb
CHANGED
data/spec/support/test_flow.rb
CHANGED
@@ -29,6 +29,8 @@ module TestFlow
|
|
29
29
|
|
30
30
|
# invoke the specified sub process
|
31
31
|
sub_process TestSubFlow
|
32
|
+
|
33
|
+
job TestWorkerJob
|
32
34
|
end
|
33
35
|
|
34
36
|
def error_task(*args)
|
@@ -65,4 +67,12 @@ module TestFlow
|
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
70
|
+
module TestWorkerJob
|
71
|
+
def self.perform(*args)
|
72
|
+
end
|
73
|
+
|
74
|
+
def perform(*args)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
68
78
|
end
|
@@ -123,11 +123,32 @@ describe Taskinator::Definition::Builder do
|
|
123
123
|
|
124
124
|
it "fails if task method is not defined" do
|
125
125
|
expect {
|
126
|
-
subject.task(:
|
126
|
+
subject.task(:undefined)
|
127
127
|
}.to raise_error(NoMethodError)
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
+
describe "#job" do
|
132
|
+
it "creates a job" do
|
133
|
+
job = double('job', :perform => true)
|
134
|
+
expect(Taskinator::Task).to receive(:define_job_task).with(process, job, args, {})
|
135
|
+
subject.job(job)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "fails if job module is nil" do
|
139
|
+
expect {
|
140
|
+
subject.job(nil)
|
141
|
+
}.to raise_error(ArgumentError)
|
142
|
+
end
|
143
|
+
|
144
|
+
# ok, fuzzy logic to determine what is ia job here!
|
145
|
+
it "fails if job module is not a job" do
|
146
|
+
expect {
|
147
|
+
subject.job(double('job', :methods => [], :instance_methods => []))
|
148
|
+
}.to raise_error(ArgumentError)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
131
152
|
describe "#sub_process" do
|
132
153
|
let(:sub_definition) do
|
133
154
|
Module.new() do
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Taskinator::JobWorker do
|
4
|
+
|
5
|
+
def mock_job(paused=false, cancelled=false)
|
6
|
+
double('job', :paused? => paused, :cancelled? => cancelled)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:uuid) { SecureRandom.uuid }
|
10
|
+
|
11
|
+
subject { Taskinator::JobWorker.new(uuid) }
|
12
|
+
|
13
|
+
it "should fetch the job" do
|
14
|
+
job = mock_job
|
15
|
+
expect(Taskinator::Task).to receive(:fetch).with(uuid) { job }
|
16
|
+
allow(job).to receive(:start!)
|
17
|
+
allow(job).to receive(:perform)
|
18
|
+
allow(job).to receive(:complete!)
|
19
|
+
subject.perform
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should start the job" do
|
23
|
+
job = mock_job
|
24
|
+
allow(Taskinator::Task).to receive(:fetch).with(uuid) { job }
|
25
|
+
expect(job).to receive(:start!) { }
|
26
|
+
allow(job).to receive(:perform)
|
27
|
+
allow(job).to receive(:complete!)
|
28
|
+
subject.perform
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should perform the job" do
|
32
|
+
job = mock_job(false, false)
|
33
|
+
allow(Taskinator::Task).to receive(:fetch).with(uuid) { job }
|
34
|
+
allow(job).to receive(:start!)
|
35
|
+
expect(job).to receive(:perform)
|
36
|
+
allow(job).to receive(:complete!)
|
37
|
+
subject.perform
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should complete the job" do
|
41
|
+
job = mock_job
|
42
|
+
allow(Taskinator::Task).to receive(:fetch).with(uuid) { job }
|
43
|
+
allow(job).to receive(:start!)
|
44
|
+
allow(job).to receive(:perform)
|
45
|
+
expect(job).to receive(:complete!)
|
46
|
+
subject.perform
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should not start if paused" do
|
50
|
+
job = mock_job(true, false)
|
51
|
+
allow(Taskinator::Task).to receive(:fetch).with(uuid) { job }
|
52
|
+
expect(job).to_not receive(:start!)
|
53
|
+
subject.perform
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not start if cancelled" do
|
57
|
+
job = mock_job(false, true)
|
58
|
+
allow(Taskinator::Task).to receive(:fetch).with(uuid) { job }
|
59
|
+
expect(job).to_not receive(:start!)
|
60
|
+
subject.perform
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should fail if job raises an error" do
|
64
|
+
job = mock_job
|
65
|
+
allow(Taskinator::Task).to receive(:fetch).with(uuid) { job }
|
66
|
+
allow(job).to receive(:start!) { raise NotImplementedError }
|
67
|
+
expect(job).to receive(:fail!).with(NotImplementedError)
|
68
|
+
subject.perform
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -9,28 +9,71 @@ describe Taskinator::Queues::DelayedJobAdapter do
|
|
9
9
|
|
10
10
|
subject { adapter.new() }
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
describe "ProcessWorker" do
|
13
|
+
it "enqueues processes" do
|
14
|
+
worker = adapter::ProcessWorker
|
15
|
+
expect {
|
16
|
+
subject.enqueue_process(double('process', :uuid => uuid))
|
17
|
+
}.to change(Delayed::Job.queue, :size).by(1)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
it "calls process worker" do
|
21
|
+
expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
|
22
|
+
adapter::ProcessWorker.new(uuid).perform
|
23
|
+
end
|
22
24
|
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
describe "TaskWorker" do
|
27
|
+
it "enqueues tasks" do
|
28
|
+
worker = adapter::TaskWorker
|
29
|
+
expect {
|
30
|
+
subject.enqueue_process(double('task', :uuid => uuid))
|
31
|
+
}.to change(Delayed::Job.queue, :size).by(1)
|
32
|
+
end
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
it "calls task worker" do
|
35
|
+
expect_any_instance_of(Taskinator::TaskWorker).to receive(:perform)
|
36
|
+
adapter::TaskWorker.new(uuid).perform
|
37
|
+
end
|
34
38
|
end
|
35
39
|
|
40
|
+
describe "JobWorker" do
|
41
|
+
it "enqueues jobs" do
|
42
|
+
worker = adapter::JobWorker
|
43
|
+
|
44
|
+
job = double('job')
|
45
|
+
job_task = double('job_task', :uuid => uuid, :job => job)
|
46
|
+
|
47
|
+
expect {
|
48
|
+
subject.enqueue_job(job_task)
|
49
|
+
}.to change(Delayed::Job.queue, :size).by(1)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "calls job worker" do
|
53
|
+
expect_any_instance_of(Taskinator::JobWorker).to receive(:perform)
|
54
|
+
adapter::JobWorker.new(uuid).perform
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:definition) do
|
58
|
+
Module.new() do
|
59
|
+
extend Taskinator::Definition
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "performs invocation on job" do
|
64
|
+
args = {:a => 1}
|
65
|
+
job = double('job')
|
66
|
+
expect(job).to receive(:perform)
|
67
|
+
|
68
|
+
job_class = double('job_class', :instance_methods => [:perform])
|
69
|
+
allow(job_class).to receive(:new).with(*args) { job }
|
70
|
+
|
71
|
+
process = Taskinator::Process::Sequential.new(definition)
|
72
|
+
job_task = Taskinator::Task.define_job_task(process, job_class, args)
|
73
|
+
|
74
|
+
allow(Taskinator::Task).to receive(:fetch).with(uuid) { job_task }
|
75
|
+
|
76
|
+
adapter::JobWorker.new(uuid).perform
|
77
|
+
end
|
78
|
+
end
|
36
79
|
end
|
@@ -9,28 +9,67 @@ describe Taskinator::Queues::ResqueAdapter do
|
|
9
9
|
|
10
10
|
subject { adapter.new() }
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
describe "ProcessWorker" do
|
13
|
+
it "enqueues processes" do
|
14
|
+
worker = adapter::ProcessWorker
|
15
|
+
subject.enqueue_process(double('process', :uuid => uuid))
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
expect(worker).to have_queued(uuid)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
it "calls process worker" do
|
21
|
+
expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
|
22
|
+
adapter::ProcessWorker.perform(uuid)
|
23
|
+
end
|
22
24
|
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
describe "TaskWorker" do
|
27
|
+
it "enqueues tasks" do
|
28
|
+
worker = adapter::TaskWorker
|
29
|
+
subject.enqueue_task(double('task', :uuid => uuid))
|
27
30
|
|
28
|
-
|
29
|
-
|
31
|
+
expect(worker).to have_queued(uuid)
|
32
|
+
end
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
it "calls task worker" do
|
35
|
+
expect_any_instance_of(Taskinator::TaskWorker).to receive(:perform)
|
36
|
+
adapter::TaskWorker.perform(uuid)
|
37
|
+
end
|
34
38
|
end
|
35
39
|
|
40
|
+
describe "JobWorker" do
|
41
|
+
it "enqueues jobs" do
|
42
|
+
worker = adapter::JobWorker
|
43
|
+
|
44
|
+
job = double('job')
|
45
|
+
job_task = double('job_task', :uuid => uuid, :job => job)
|
46
|
+
|
47
|
+
subject.enqueue_job(job_task)
|
48
|
+
expect(worker).to have_queued(uuid)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "calls job worker" do
|
52
|
+
expect_any_instance_of(Taskinator::JobWorker).to receive(:perform)
|
53
|
+
adapter::JobWorker.perform(uuid)
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:definition) do
|
57
|
+
Module.new() do
|
58
|
+
extend Taskinator::Definition
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "performs invocation on job" do
|
63
|
+
args = {:a => 1}
|
64
|
+
job_class = double('job_class', :methods => [:perform])
|
65
|
+
expect(job_class).to receive(:perform).with(*args)
|
66
|
+
|
67
|
+
process = Taskinator::Process::Sequential.new(definition)
|
68
|
+
job_task = Taskinator::Task.define_job_task(process, job_class, args)
|
69
|
+
|
70
|
+
allow(Taskinator::Task).to receive(:fetch).with(uuid) { job_task }
|
71
|
+
|
72
|
+
adapter::JobWorker.perform(uuid)
|
73
|
+
end
|
74
|
+
end
|
36
75
|
end
|
@@ -9,28 +9,71 @@ describe Taskinator::Queues::SidekiqAdapter do
|
|
9
9
|
|
10
10
|
subject { adapter.new() }
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
describe "ProcessWorker" do
|
13
|
+
it "enqueues processes" do
|
14
|
+
worker = adapter::ProcessWorker
|
15
|
+
expect {
|
16
|
+
subject.enqueue_process(double('process', :uuid => uuid))
|
17
|
+
}.to change(worker.jobs, :size).by(1)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
it "calls process worker" do
|
21
|
+
expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
|
22
|
+
adapter::ProcessWorker.new().perform(uuid)
|
23
|
+
end
|
22
24
|
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
describe "TaskWorker" do
|
27
|
+
it "enqueues tasks" do
|
28
|
+
worker = adapter::TaskWorker
|
29
|
+
expect {
|
30
|
+
subject.enqueue_task(double('task', :uuid => uuid))
|
31
|
+
}.to change(worker.jobs, :size).by(1)
|
32
|
+
end
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
it "calls task worker" do
|
35
|
+
expect_any_instance_of(Taskinator::TaskWorker).to receive(:perform)
|
36
|
+
adapter::TaskWorker.new().perform(uuid)
|
37
|
+
end
|
34
38
|
end
|
35
39
|
|
40
|
+
describe "JobWorker" do
|
41
|
+
it "enqueues jobs" do
|
42
|
+
worker = adapter::JobWorker
|
43
|
+
|
44
|
+
job = double('job', :get_sidekiq_options => {})
|
45
|
+
job_task = double('job_task', :uuid => uuid, :job => job)
|
46
|
+
|
47
|
+
expect {
|
48
|
+
subject.enqueue_job(job_task)
|
49
|
+
}.to change(worker.jobs, :size).by(1)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "calls job worker" do
|
53
|
+
expect_any_instance_of(Taskinator::JobWorker).to receive(:perform)
|
54
|
+
adapter::JobWorker.new().perform(uuid)
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:definition) do
|
58
|
+
Module.new() do
|
59
|
+
extend Taskinator::Definition
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "performs invocation on job" do
|
64
|
+
args = {:a => 1}
|
65
|
+
job = double('job')
|
66
|
+
expect(job).to receive(:perform).with(*args)
|
67
|
+
|
68
|
+
job_class = double('job_class', :get_sidekiq_options => {}, :instance_methods => [:perform])
|
69
|
+
allow(job_class).to receive(:new) { job }
|
70
|
+
|
71
|
+
process = Taskinator::Process::Sequential.new(definition)
|
72
|
+
job_task = Taskinator::Task.define_job_task(process, job_class, args)
|
73
|
+
|
74
|
+
allow(Taskinator::Task).to receive(:fetch).with(uuid) { job_task }
|
75
|
+
|
76
|
+
adapter::JobWorker.new().perform(uuid)
|
77
|
+
end
|
78
|
+
end
|
36
79
|
end
|
@@ -201,6 +201,51 @@ describe Taskinator::Task do
|
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
204
|
+
describe Taskinator::Task::Job do
|
205
|
+
|
206
|
+
module TestJob
|
207
|
+
def self.perform(*args)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
it_should_behave_like "a task", Taskinator::Task::Job do
|
212
|
+
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
213
|
+
let(:task) { Taskinator::Task.define_job_task(process, TestJob, {:a => 1, :b => 2}) }
|
214
|
+
end
|
215
|
+
|
216
|
+
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
217
|
+
subject { Taskinator::Task.define_job_task(process, TestJob, {:a => 1, :b => 2}) }
|
218
|
+
|
219
|
+
describe "#perform" do
|
220
|
+
it {
|
221
|
+
block = SpecSupport::Block.new()
|
222
|
+
expect(block).to receive(:call).with(TestJob, {:a => 1, :b => 2})
|
223
|
+
|
224
|
+
subject.perform &block
|
225
|
+
}
|
226
|
+
end
|
227
|
+
|
228
|
+
describe "#accept" do
|
229
|
+
it {
|
230
|
+
expect(subject).to receive(:accept)
|
231
|
+
subject.save
|
232
|
+
}
|
233
|
+
|
234
|
+
it {
|
235
|
+
visitor = double('visitor')
|
236
|
+
expect(visitor).to receive(:visit_type).with(:definition)
|
237
|
+
expect(visitor).to receive(:visit_attribute).with(:uuid)
|
238
|
+
expect(visitor).to receive(:visit_process_reference).with(:process)
|
239
|
+
expect(visitor).to receive(:visit_task_reference).with(:next)
|
240
|
+
expect(visitor).to receive(:visit_args).with(:options)
|
241
|
+
expect(visitor).to receive(:visit_type).with(:job)
|
242
|
+
expect(visitor).to receive(:visit_args).with(:args)
|
243
|
+
|
244
|
+
subject.accept(visitor)
|
245
|
+
}
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
204
249
|
describe Taskinator::Task::SubProcess do
|
205
250
|
it_should_behave_like "a task", Taskinator::Task::SubProcess do
|
206
251
|
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
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.
|
4
|
+
version: 0.0.4
|
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-09-
|
11
|
+
date: 2014-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -230,6 +230,7 @@ files:
|
|
230
230
|
- lib/taskinator/definition.rb
|
231
231
|
- lib/taskinator/definition/builder.rb
|
232
232
|
- lib/taskinator/executor.rb
|
233
|
+
- lib/taskinator/job_worker.rb
|
233
234
|
- lib/taskinator/logger.rb
|
234
235
|
- lib/taskinator/persistence.rb
|
235
236
|
- lib/taskinator/process.rb
|
@@ -258,6 +259,7 @@ files:
|
|
258
259
|
- spec/taskinator/definition_spec.rb
|
259
260
|
- spec/taskinator/executor_spec.rb
|
260
261
|
- spec/taskinator/intermodal_spec.rb
|
262
|
+
- spec/taskinator/job_worker_spec.rb
|
261
263
|
- spec/taskinator/persistence_spec.rb
|
262
264
|
- spec/taskinator/process_spec.rb
|
263
265
|
- spec/taskinator/process_worker_spec.rb
|
@@ -309,6 +311,7 @@ test_files:
|
|
309
311
|
- spec/taskinator/definition_spec.rb
|
310
312
|
- spec/taskinator/executor_spec.rb
|
311
313
|
- spec/taskinator/intermodal_spec.rb
|
314
|
+
- spec/taskinator/job_worker_spec.rb
|
312
315
|
- spec/taskinator/persistence_spec.rb
|
313
316
|
- spec/taskinator/process_spec.rb
|
314
317
|
- spec/taskinator/process_worker_spec.rb
|