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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 733dcb0269d80bc0685527f80cbfa4fc76476d25
4
- data.tar.gz: 0d67598fedf6988febd3fb74126243f31868a99b
3
+ metadata.gz: 3ae6a63807d0e3e2cb0c513f348eeab155abe830
4
+ data.tar.gz: ce5a3c1168ff6a3d1bcb623452c458dac6b96dee
5
5
  SHA512:
6
- metadata.gz: 4b0a72311954c8f95d6d20619487fecb754e68e0fc6fdd6dee087fa882db321a56644ac06a8bb2f997252656ebf62598b7227a9c0f9c79867643d470a5fbabf1
7
- data.tar.gz: 8608aa783cc093aa559ad3513ea308234b16092fbd70299034a3d90f6d505d3eeb9378a11c602851a748553c2846f49f0f3670629d350e75a7b5e548a059b7f6
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.3)
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.5)
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.2)
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.0.0)
82
- rspec-core (~> 3.0.0)
83
- rspec-expectations (~> 3.0.0)
84
- rspec-mocks (~> 3.0.0)
85
- rspec-core (3.0.4)
86
- rspec-support (~> 3.0.0)
87
- rspec-expectations (3.0.4)
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.0.0)
90
- rspec-mocks (3.0.4)
91
- rspec-support (~> 3.0.0)
92
- rspec-support (3.0.4)
93
- sidekiq (3.2.3)
94
- celluloid (>= 0.15.2)
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
- value = @instance.send(attribute)
172
- @hmset += [attribute, YAML.dump(value)] if value
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
- value = @attribute_values[attribute]
262
- if value
263
- args = YAML.load(value)
264
- @instance.instance_variable_set("@#{attribute}", args)
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
@@ -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 JSON
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
@@ -1,3 +1,3 @@
1
1
  module Taskinator
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/taskinator.rb CHANGED
@@ -19,6 +19,7 @@ require 'taskinator/tasks'
19
19
  require 'taskinator/process'
20
20
 
21
21
  require 'taskinator/task_worker'
22
+ require 'taskinator/job_worker'
22
23
  require 'taskinator/process_worker'
23
24
 
24
25
  require 'taskinator/executor'
@@ -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(:undefined_method)
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
- it "enqueues processes" do
13
- worker = adapter::ProcessWorker
14
- expect {
15
- subject.enqueue_process(double('process', :uuid => uuid))
16
- }.to change(Delayed::Job.queue, :size).by(1)
17
- end
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
- it "calls process worker" do
20
- expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
21
- adapter::ProcessWorker.new(uuid).perform
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
- it "enqueues tasks" do
25
- worker = adapter::TaskWorker
26
- expect {
27
- subject.enqueue_process(double('task', :uuid => uuid))
28
- }.to change(Delayed::Job.queue, :size).by(1)
29
- end
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
- it "calls task worker" do
32
- expect_any_instance_of(Taskinator::TaskWorker).to receive(:perform)
33
- adapter::TaskWorker.new(uuid).perform
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
- it "enqueues processes" do
13
- worker = adapter::ProcessWorker
14
- subject.enqueue_process(double('process', :uuid => uuid))
12
+ describe "ProcessWorker" do
13
+ it "enqueues processes" do
14
+ worker = adapter::ProcessWorker
15
+ subject.enqueue_process(double('process', :uuid => uuid))
15
16
 
16
- expect(worker).to have_queued(uuid)
17
- end
17
+ expect(worker).to have_queued(uuid)
18
+ end
18
19
 
19
- it "calls process worker" do
20
- expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
21
- adapter::ProcessWorker.perform(uuid)
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
- it "enqueues tasks" do
25
- worker = adapter::TaskWorker
26
- subject.enqueue_task(double('task', :uuid => uuid))
26
+ describe "TaskWorker" do
27
+ it "enqueues tasks" do
28
+ worker = adapter::TaskWorker
29
+ subject.enqueue_task(double('task', :uuid => uuid))
27
30
 
28
- expect(worker).to have_queued(uuid)
29
- end
31
+ expect(worker).to have_queued(uuid)
32
+ end
30
33
 
31
- it "calls task worker" do
32
- expect_any_instance_of(Taskinator::TaskWorker).to receive(:perform)
33
- adapter::TaskWorker.perform(uuid)
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
- it "enqueues processes" do
13
- worker = adapter::ProcessWorker
14
- expect {
15
- subject.enqueue_process(double('process', :uuid => uuid))
16
- }.to change(worker.jobs, :size).by(1)
17
- end
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
- it "calls process worker" do
20
- expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
21
- adapter::ProcessWorker.new().perform(uuid)
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
- it "enqueues tasks" do
25
- worker = adapter::TaskWorker
26
- expect {
27
- subject.enqueue_task(double('task', :uuid => uuid))
28
- }.to change(worker.jobs, :size).by(1)
29
- end
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
- it "calls task worker" do
32
- expect_any_instance_of(Taskinator::TaskWorker).to receive(:perform)
33
- adapter::TaskWorker.new().perform(uuid)
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.3
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-02 00:00:00.000000000 Z
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