bumbleworks 0.0.34 → 0.0.35
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.
- data/lib/bumbleworks/configuration.rb +8 -0
- data/lib/bumbleworks/task.rb +39 -20
- data/lib/bumbleworks/task/finder.rb +13 -3
- data/lib/bumbleworks/version.rb +1 -1
- data/spec/lib/bumbleworks/configuration_spec.rb +12 -0
- data/spec/lib/bumbleworks/task/finder_spec.rb +34 -0
- data/spec/lib/bumbleworks/task_spec.rb +80 -13
- metadata +10 -3
@@ -83,6 +83,10 @@ module Bumbleworks
|
|
83
83
|
# default: Bumbleworks::SimpleLogger
|
84
84
|
define_setting :logger
|
85
85
|
|
86
|
+
# All before_* and after_* callback methods prototyped in Tasks::Base will
|
87
|
+
# also be called on all registered observers.
|
88
|
+
define_setting :observers
|
89
|
+
|
86
90
|
def initialize
|
87
91
|
@storage_adapters = []
|
88
92
|
end
|
@@ -149,6 +153,10 @@ module Bumbleworks
|
|
149
153
|
@logger ||= Bumbleworks::SimpleLogger
|
150
154
|
end
|
151
155
|
|
156
|
+
def observers
|
157
|
+
@observers ||= []
|
158
|
+
end
|
159
|
+
|
152
160
|
# Clears all memoize variables and configuration settings
|
153
161
|
#
|
154
162
|
def clear!
|
data/lib/bumbleworks/task.rb
CHANGED
@@ -33,7 +33,7 @@ module Bumbleworks
|
|
33
33
|
|
34
34
|
def method_missing(method, *args)
|
35
35
|
if Finder.new.respond_to?(method)
|
36
|
-
return Finder.new.send(method, *args)
|
36
|
+
return Finder.new([], self).send(method, *args)
|
37
37
|
end
|
38
38
|
super
|
39
39
|
end
|
@@ -91,23 +91,37 @@ module Bumbleworks
|
|
91
91
|
klass = Bumbleworks::Support.constantize("#{klass_name}Task")
|
92
92
|
end
|
93
93
|
|
94
|
+
def call_before_hooks(action, *args)
|
95
|
+
call_hooks(:before, action, *args)
|
96
|
+
end
|
97
|
+
|
98
|
+
def call_after_hooks(action, *args)
|
99
|
+
call_hooks(:after, action, *args)
|
100
|
+
end
|
101
|
+
|
102
|
+
def with_hooks(action, *args, &block)
|
103
|
+
call_before_hooks(action, *args)
|
104
|
+
yield
|
105
|
+
call_after_hooks(action, *args)
|
106
|
+
end
|
107
|
+
|
94
108
|
# update workitem with changes to fields & params
|
95
109
|
def update(metadata = {})
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
110
|
+
with_hooks(:update, metadata) do
|
111
|
+
update_workitem
|
112
|
+
log(:update, metadata)
|
113
|
+
end
|
100
114
|
end
|
101
115
|
|
102
116
|
# proceed workitem (saving changes to fields)
|
103
117
|
def complete(metadata = {})
|
104
118
|
raise NotCompletable.new(not_completable_error_message) unless completable?
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
119
|
+
with_hooks(:update, metadata) do
|
120
|
+
with_hooks(:complete, metadata) do
|
121
|
+
proceed_workitem
|
122
|
+
log(:complete, metadata)
|
123
|
+
end
|
124
|
+
end
|
111
125
|
end
|
112
126
|
|
113
127
|
# Token used to claim task, nil if not claimed
|
@@ -122,10 +136,10 @@ module Bumbleworks
|
|
122
136
|
|
123
137
|
# Claim task and assign token to claimant
|
124
138
|
def claim(token)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
139
|
+
with_hooks(:claim, token) do
|
140
|
+
set_claimant(token)
|
141
|
+
log(:claim)
|
142
|
+
end
|
129
143
|
end
|
130
144
|
|
131
145
|
# true if task is claimed
|
@@ -136,15 +150,15 @@ module Bumbleworks
|
|
136
150
|
# release claim on task.
|
137
151
|
def release
|
138
152
|
current_claimant = claimant
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
153
|
+
with_hooks(:release, current_claimant) do
|
154
|
+
log(:release)
|
155
|
+
set_claimant(nil)
|
156
|
+
end
|
143
157
|
end
|
144
158
|
|
145
159
|
def on_dispatch
|
146
160
|
log(:dispatch)
|
147
|
-
|
161
|
+
call_after_hooks(:dispatch)
|
148
162
|
end
|
149
163
|
|
150
164
|
def log(action, metadata = {})
|
@@ -170,6 +184,11 @@ module Bumbleworks
|
|
170
184
|
end
|
171
185
|
|
172
186
|
private
|
187
|
+
def call_hooks(phase, action, *args)
|
188
|
+
(Bumbleworks.observers + [self]).each do |observer|
|
189
|
+
observer.send(:"#{phase}_#{action}", *args)
|
190
|
+
end
|
191
|
+
end
|
173
192
|
|
174
193
|
def displayify(modifier, options = {})
|
175
194
|
task_name = Bumbleworks::Support.send(modifier, nickname)
|
@@ -3,8 +3,9 @@ module Bumbleworks
|
|
3
3
|
class Finder
|
4
4
|
include Enumerable
|
5
5
|
|
6
|
-
def initialize(queries = [])
|
6
|
+
def initialize(queries = [], task_class = Bumbleworks::Task)
|
7
7
|
@queries = queries
|
8
|
+
@task_class = task_class
|
8
9
|
end
|
9
10
|
|
10
11
|
def by_nickname(nickname)
|
@@ -22,6 +23,15 @@ module Bumbleworks
|
|
22
23
|
for_roles([identifier])
|
23
24
|
end
|
24
25
|
|
26
|
+
def unclaimed(check = true)
|
27
|
+
@queries << proc { |wi| wi['fields']['params']['claimant'].nil? == check }
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def claimed
|
32
|
+
unclaimed(false)
|
33
|
+
end
|
34
|
+
|
25
35
|
def for_claimant(token)
|
26
36
|
@queries << proc { |wi| wi['fields']['params']['claimant'] == token }
|
27
37
|
self
|
@@ -57,7 +67,7 @@ module Bumbleworks
|
|
57
67
|
start_time = Time.now
|
58
68
|
while first.nil?
|
59
69
|
if (Time.now - start_time) > options[:timeout]
|
60
|
-
raise
|
70
|
+
raise @task_class::AvailabilityTimeout, "No tasks found matching criteria in time"
|
61
71
|
end
|
62
72
|
sleep 0.1
|
63
73
|
end
|
@@ -68,7 +78,7 @@ module Bumbleworks
|
|
68
78
|
|
69
79
|
def from_workitems(workitems)
|
70
80
|
workitems.map { |wi|
|
71
|
-
|
81
|
+
@task_class.new(wi) if wi.params['task']
|
72
82
|
}.compact
|
73
83
|
end
|
74
84
|
end
|
data/lib/bumbleworks/version.rb
CHANGED
@@ -192,6 +192,18 @@ describe Bumbleworks::Configuration do
|
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
|
+
describe '#observers' do
|
196
|
+
it 'is empty by default' do
|
197
|
+
configuration.observers.should be_empty
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'returns the registered observers' do
|
201
|
+
configuration.observers = [:smash, :pumpkin]
|
202
|
+
configuration.observers << :rhubarb
|
203
|
+
configuration.observers.should == [:smash, :pumpkin, :rhubarb]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
195
207
|
describe "#storage" do
|
196
208
|
it 'can set storage directly' do
|
197
209
|
storage = double("Storage")
|
@@ -0,0 +1,34 @@
|
|
1
|
+
describe Bumbleworks::Task::Finder do
|
2
|
+
before :each do
|
3
|
+
Bumbleworks.reset!
|
4
|
+
Bumbleworks.storage = {}
|
5
|
+
Bumbleworks::Ruote.register_participants
|
6
|
+
Bumbleworks.start_worker!
|
7
|
+
Bumbleworks.define_process 'dog-lifecycle' do
|
8
|
+
concurrence do
|
9
|
+
dog :task => 'eat'
|
10
|
+
dog :task => 'bark'
|
11
|
+
dog :task => 'pet_dog'
|
12
|
+
cat :task => 'skip_and_jump'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#all' do
|
18
|
+
it 'uses Bumbleworks::Task class by default for task generation' do
|
19
|
+
Bumbleworks.launch!('dog-lifecycle')
|
20
|
+
Bumbleworks.dashboard.wait_for(:cat)
|
21
|
+
tasks = Bumbleworks::Task::Finder.new.all
|
22
|
+
tasks.should be_all { |t| t.class == Bumbleworks::Task }
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'uses provided class for task generation' do
|
26
|
+
class MyOwnTask < Bumbleworks::Task; end
|
27
|
+
Bumbleworks.launch!('dog-lifecycle')
|
28
|
+
Bumbleworks.dashboard.wait_for(:cat)
|
29
|
+
tasks = Bumbleworks::Task::Finder.new([], MyOwnTask).all
|
30
|
+
tasks.should be_all { |t| t.class == MyOwnTask }
|
31
|
+
Object.send(:remove_const, :MyOwnTask)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -80,6 +80,20 @@ describe Bumbleworks::Task do
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
+
[:before, :after].each do |phase|
|
84
|
+
describe "#call_#{phase}_hooks" do
|
85
|
+
it "calls #{phase} hooks on task and all observers" do
|
86
|
+
observer1, observer2 = double('observer1'), double('observer2')
|
87
|
+
Bumbleworks.observers = [observer1, observer2]
|
88
|
+
task = described_class.new(workflow_item)
|
89
|
+
task.should_receive(:"#{phase}_snoogle").with(:chachunga, :faloop)
|
90
|
+
observer1.should_receive(:"#{phase}_snoogle").with(:chachunga, :faloop)
|
91
|
+
observer2.should_receive(:"#{phase}_snoogle").with(:chachunga, :faloop)
|
92
|
+
task.send(:"call_#{phase}_hooks", :snoogle, :chachunga, :faloop)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
83
97
|
describe '#on_dispatch' do
|
84
98
|
before :each do
|
85
99
|
Bumbleworks.define_process 'planting_a_noodle' do
|
@@ -89,7 +103,7 @@ describe Bumbleworks::Task do
|
|
89
103
|
end
|
90
104
|
end
|
91
105
|
|
92
|
-
it 'is called when task is dispatched
|
106
|
+
it 'is called when task is dispatched' do
|
93
107
|
described_class.any_instance.should_receive(:on_dispatch)
|
94
108
|
Bumbleworks.launch!('planting_a_noodle')
|
95
109
|
Bumbleworks.dashboard.wait_for(:horse_feeder)
|
@@ -105,10 +119,10 @@ describe Bumbleworks::Task do
|
|
105
119
|
log_entry[:target_id].should == task.id
|
106
120
|
end
|
107
121
|
|
108
|
-
it 'calls
|
122
|
+
it 'calls after hooks' do
|
109
123
|
task = described_class.new(workflow_item)
|
110
124
|
task.stub(:log)
|
111
|
-
task.should_receive(:
|
125
|
+
task.should_receive(:call_after_hooks).with(:dispatch)
|
112
126
|
task.on_dispatch
|
113
127
|
end
|
114
128
|
end
|
@@ -256,6 +270,51 @@ describe Bumbleworks::Task do
|
|
256
270
|
end
|
257
271
|
end
|
258
272
|
|
273
|
+
describe '.unclaimed' do
|
274
|
+
it 'returns all unclaimed tasks' do
|
275
|
+
Bumbleworks.define_process 'dog-lifecycle' do
|
276
|
+
concurrence do
|
277
|
+
dog :task => 'eat'
|
278
|
+
dog :task => 'bark'
|
279
|
+
dog :task => 'pet_dog'
|
280
|
+
cat :task => 'skip_and_jump'
|
281
|
+
end
|
282
|
+
dog :task => 'nap'
|
283
|
+
end
|
284
|
+
Bumbleworks.launch!('dog-lifecycle')
|
285
|
+
Bumbleworks.dashboard.wait_for(:cat)
|
286
|
+
@unclaimed = described_class.unclaimed
|
287
|
+
@unclaimed.map(&:nickname).should =~ ['eat', 'bark', 'pet_dog', 'skip_and_jump']
|
288
|
+
described_class.all.each do |t|
|
289
|
+
t.claim('radish') unless ['pet_dog', 'bark'].include?(t.nickname)
|
290
|
+
end
|
291
|
+
@unclaimed = described_class.unclaimed
|
292
|
+
@unclaimed.map(&:nickname).should =~ ['pet_dog', 'bark']
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe '.claimed' do
|
297
|
+
it 'returns all claimed tasks' do
|
298
|
+
Bumbleworks.define_process 'dog-lifecycle' do
|
299
|
+
concurrence do
|
300
|
+
dog :task => 'eat'
|
301
|
+
dog :task => 'bark'
|
302
|
+
dog :task => 'pet_dog'
|
303
|
+
cat :task => 'skip_and_jump'
|
304
|
+
end
|
305
|
+
dog :task => 'nap'
|
306
|
+
end
|
307
|
+
Bumbleworks.launch!('dog-lifecycle')
|
308
|
+
Bumbleworks.dashboard.wait_for(:cat)
|
309
|
+
described_class.claimed.should be_empty
|
310
|
+
described_class.all.each_with_index do |t, i|
|
311
|
+
t.claim("radish_#{i}") unless ['pet_dog', 'bark'].include?(t.nickname)
|
312
|
+
end
|
313
|
+
@claimed = described_class.claimed
|
314
|
+
@claimed.map(&:nickname).should =~ ['eat', 'skip_and_jump']
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
259
318
|
describe '.all' do
|
260
319
|
before :each do
|
261
320
|
Bumbleworks.define_process 'dog-lifecycle' do
|
@@ -282,6 +341,14 @@ describe Bumbleworks::Task do
|
|
282
341
|
['dog_legs', 'skip_and_jump']
|
283
342
|
]
|
284
343
|
end
|
344
|
+
|
345
|
+
it 'uses subclass for generation of tasks' do
|
346
|
+
class MyOwnTask < Bumbleworks::Task; end
|
347
|
+
Bumbleworks.dashboard.wait_for(:dog_legs)
|
348
|
+
tasks = MyOwnTask.all
|
349
|
+
tasks.should be_all { |t| t.class == MyOwnTask }
|
350
|
+
Object.send(:remove_const, :MyOwnTask)
|
351
|
+
end
|
285
352
|
end
|
286
353
|
|
287
354
|
describe '#[], #[]=' do
|
@@ -471,10 +538,10 @@ describe Bumbleworks::Task do
|
|
471
538
|
@task.params['claimed_at'].should be_nil
|
472
539
|
end
|
473
540
|
|
474
|
-
it 'calls
|
475
|
-
@task.should_receive(:
|
541
|
+
it 'calls with hooks' do
|
542
|
+
@task.should_receive(:call_before_hooks).with(:release, 'boss').ordered
|
476
543
|
@task.should_receive(:set_claimant).ordered
|
477
|
-
@task.should_receive(:
|
544
|
+
@task.should_receive(:call_after_hooks).with(:release, 'boss').ordered
|
478
545
|
@task.release
|
479
546
|
end
|
480
547
|
|
@@ -508,12 +575,12 @@ describe Bumbleworks::Task do
|
|
508
575
|
task.fields['meal'].should == 'salted_rhubarb'
|
509
576
|
end
|
510
577
|
|
511
|
-
it 'calls
|
578
|
+
it 'calls with hooks' do
|
512
579
|
task = described_class.new(workflow_item)
|
513
580
|
task.stub(:log)
|
514
|
-
task.should_receive(:
|
581
|
+
task.should_receive(:call_before_hooks).with(:update, :argue_mints).ordered
|
515
582
|
task.should_receive(:update_workitem).ordered
|
516
|
-
task.should_receive(:
|
583
|
+
task.should_receive(:call_after_hooks).with(:update, :argue_mints).ordered
|
517
584
|
task.update(:argue_mints)
|
518
585
|
end
|
519
586
|
|
@@ -570,11 +637,11 @@ describe Bumbleworks::Task do
|
|
570
637
|
it 'calls update and complete callbacks' do
|
571
638
|
task = described_class.new(workflow_item)
|
572
639
|
task.stub(:log)
|
573
|
-
task.should_receive(:
|
574
|
-
task.should_receive(:
|
640
|
+
task.should_receive(:call_before_hooks).with(:update, :argue_mints).ordered
|
641
|
+
task.should_receive(:call_before_hooks).with(:complete, :argue_mints).ordered
|
575
642
|
task.should_receive(:proceed_workitem).ordered
|
576
|
-
task.should_receive(:
|
577
|
-
task.should_receive(:
|
643
|
+
task.should_receive(:call_after_hooks).with(:complete, :argue_mints).ordered
|
644
|
+
task.should_receive(:call_after_hooks).with(:update, :argue_mints).ordered
|
578
645
|
task.complete(:argue_mints)
|
579
646
|
end
|
580
647
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bumbleworks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.35
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2013-
|
15
|
+
date: 2013-09-12 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: ruote
|
@@ -213,6 +213,7 @@ files:
|
|
213
213
|
- spec/lib/bumbleworks/simple_logger_spec.rb
|
214
214
|
- spec/lib/bumbleworks/storage_adapter_spec.rb
|
215
215
|
- spec/lib/bumbleworks/support_spec.rb
|
216
|
+
- spec/lib/bumbleworks/task/finder_spec.rb
|
216
217
|
- spec/lib/bumbleworks/task_spec.rb
|
217
218
|
- spec/lib/bumbleworks/tree_builder_spec.rb
|
218
219
|
- spec/lib/bumbleworks/workitem_entity_storage_spec.rb
|
@@ -233,12 +234,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
233
234
|
- - ! '>='
|
234
235
|
- !ruby/object:Gem::Version
|
235
236
|
version: '0'
|
237
|
+
segments:
|
238
|
+
- 0
|
239
|
+
hash: -265632514630841988
|
236
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
241
|
none: false
|
238
242
|
requirements:
|
239
243
|
- - ! '>='
|
240
244
|
- !ruby/object:Gem::Version
|
241
245
|
version: '0'
|
246
|
+
segments:
|
247
|
+
- 0
|
248
|
+
hash: -265632514630841988
|
242
249
|
requirements: []
|
243
250
|
rubyforge_project:
|
244
251
|
rubygems_version: 1.8.23
|
@@ -273,6 +280,7 @@ test_files:
|
|
273
280
|
- spec/lib/bumbleworks/simple_logger_spec.rb
|
274
281
|
- spec/lib/bumbleworks/storage_adapter_spec.rb
|
275
282
|
- spec/lib/bumbleworks/support_spec.rb
|
283
|
+
- spec/lib/bumbleworks/task/finder_spec.rb
|
276
284
|
- spec/lib/bumbleworks/task_spec.rb
|
277
285
|
- spec/lib/bumbleworks/tree_builder_spec.rb
|
278
286
|
- spec/lib/bumbleworks/workitem_entity_storage_spec.rb
|
@@ -280,4 +288,3 @@ test_files:
|
|
280
288
|
- spec/spec_helper.rb
|
281
289
|
- spec/support/path_helpers.rb
|
282
290
|
- spec/support/tracer.rb
|
283
|
-
has_rdoc:
|