bumbleworks 0.0.25 → 0.0.26
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/task.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "bumbleworks/tasks/base"
|
|
2
2
|
require "bumbleworks/workitem_entity_storage"
|
|
3
|
+
require "bumbleworks/task/finder"
|
|
3
4
|
|
|
4
5
|
module Bumbleworks
|
|
5
6
|
class Task
|
|
@@ -8,6 +9,7 @@ module Bumbleworks
|
|
|
8
9
|
class AlreadyClaimed < StandardError; end
|
|
9
10
|
class MissingWorkitem < StandardError; end
|
|
10
11
|
class NotCompletable < StandardError; end
|
|
12
|
+
class AvailabilityTimeout < StandardError; end
|
|
11
13
|
|
|
12
14
|
extend Forwardable
|
|
13
15
|
delegate [:sid, :fei, :fields, :params, :participant_name, :wfid, :wf_name] => :@workitem
|
|
@@ -29,24 +31,11 @@ module Bumbleworks
|
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return [] unless identifiers.is_a?(Array)
|
|
38
|
-
workitems = identifiers.collect { |identifier|
|
|
39
|
-
storage_participant.by_participant(identifier)
|
|
40
|
-
}.flatten.uniq
|
|
41
|
-
from_workitems(workitems)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def for_claimant(token)
|
|
45
|
-
all.select { |t| t.claimant == token }
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def all
|
|
49
|
-
from_workitems(storage_participant.all)
|
|
34
|
+
def method_missing(method, *args)
|
|
35
|
+
if Finder.new.respond_to?(method)
|
|
36
|
+
return Finder.new.send(method, *args)
|
|
37
|
+
end
|
|
38
|
+
super
|
|
50
39
|
end
|
|
51
40
|
|
|
52
41
|
def find_by_id(sid)
|
|
@@ -60,12 +49,6 @@ module Bumbleworks
|
|
|
60
49
|
def storage_participant
|
|
61
50
|
Bumbleworks.dashboard.storage_participant
|
|
62
51
|
end
|
|
63
|
-
|
|
64
|
-
def from_workitems(workitems)
|
|
65
|
-
workitems.map { |wi|
|
|
66
|
-
new(wi) if wi.params['task']
|
|
67
|
-
}.compact
|
|
68
|
-
end
|
|
69
52
|
end
|
|
70
53
|
|
|
71
54
|
def initialize(workitem)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module Bumbleworks
|
|
2
|
+
class Task
|
|
3
|
+
class Finder
|
|
4
|
+
include Enumerable
|
|
5
|
+
|
|
6
|
+
def initialize(queries = [])
|
|
7
|
+
@queries = queries
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def by_nickname(nickname)
|
|
11
|
+
@queries << proc { |wi| wi['fields']['params']['task'] == nickname }
|
|
12
|
+
self
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def for_roles(identifiers)
|
|
16
|
+
identifiers ||= []
|
|
17
|
+
@queries << proc { |wi| identifiers.include?(wi['participant_name']) }
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def for_role(identifier)
|
|
22
|
+
for_roles([identifier])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def for_claimant(token)
|
|
26
|
+
@queries << proc { |wi| wi['fields']['params']['claimant'] == token }
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def for_entity(entity)
|
|
31
|
+
@queries << proc { |wi|
|
|
32
|
+
(wi['fields'][:entity_type] || wi['fields']['entity_type']) == entity.class.name &&
|
|
33
|
+
(wi['fields'][:entity_id] || wi['fields']['entity_id']) == entity.identifier
|
|
34
|
+
}
|
|
35
|
+
self
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def all
|
|
39
|
+
workitems = Bumbleworks.dashboard.storage_participant.send(:do_select, {}) { |wi|
|
|
40
|
+
@queries.all? { |q| q.call(wi) }
|
|
41
|
+
}
|
|
42
|
+
from_workitems(workitems)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def each(&block)
|
|
46
|
+
all.each(&block)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def empty?
|
|
50
|
+
all.empty?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def next_available(options = {})
|
|
54
|
+
options[:timeout] ||= 5
|
|
55
|
+
|
|
56
|
+
start_time = Time.now
|
|
57
|
+
while first.nil?
|
|
58
|
+
if (Time.now - start_time) > options[:timeout]
|
|
59
|
+
raise Bumbleworks::Task::AvailabilityTimeout, "No tasks found matching criteria in time"
|
|
60
|
+
end
|
|
61
|
+
sleep 0.1
|
|
62
|
+
end
|
|
63
|
+
first
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def from_workitems(workitems)
|
|
69
|
+
workitems.map { |wi|
|
|
70
|
+
Task.new(wi) if wi.params['task']
|
|
71
|
+
}.compact
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
data/lib/bumbleworks/version.rb
CHANGED
|
@@ -5,8 +5,8 @@ module Bumbleworks
|
|
|
5
5
|
def entity(options = {})
|
|
6
6
|
@entity = nil if options[:reload] == true
|
|
7
7
|
@entity ||= if has_entity_fields?
|
|
8
|
-
klass = Bumbleworks::Support.constantize(
|
|
9
|
-
entity = klass.first_by_identifier(
|
|
8
|
+
klass = Bumbleworks::Support.constantize(entity_type)
|
|
9
|
+
entity = klass.first_by_identifier(entity_id)
|
|
10
10
|
end
|
|
11
11
|
raise EntityNotFound unless @entity
|
|
12
12
|
@entity
|
|
@@ -19,7 +19,17 @@ module Bumbleworks
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def has_entity_fields?
|
|
22
|
-
|
|
22
|
+
entity_id && entity_type
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def entity_id
|
|
28
|
+
workitem.fields[:entity_id] || workitem.fields['entity_id']
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def entity_type
|
|
32
|
+
workitem.fields[:entity_type] || workitem.fields['entity_type']
|
|
23
33
|
end
|
|
24
34
|
end
|
|
25
35
|
end
|
|
@@ -91,7 +91,7 @@ describe Bumbleworks::Task do
|
|
|
91
91
|
it 'logs dispatch' do
|
|
92
92
|
Bumbleworks.launch!('planting_a_noodle')
|
|
93
93
|
Bumbleworks.dashboard.wait_for(:horse_feeder)
|
|
94
|
-
task = described_class.for_role('horse_feeder').
|
|
94
|
+
task = described_class.for_role('horse_feeder').first
|
|
95
95
|
log_entry = Bumbleworks.logger.entries.last[:entry]
|
|
96
96
|
log_entry[:action].should == :dispatch
|
|
97
97
|
log_entry[:target_type].should == 'Task'
|
|
@@ -230,9 +230,22 @@ describe Bumbleworks::Task do
|
|
|
230
230
|
end
|
|
231
231
|
|
|
232
232
|
describe '.for_role' do
|
|
233
|
-
it '
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
it 'returns all tasks for given role' do
|
|
234
|
+
Bumbleworks.define_process 'chalking' do
|
|
235
|
+
concurrence do
|
|
236
|
+
chalker :task => 'make_chalk_drawings'
|
|
237
|
+
hagrid :task => 'moan_endearingly'
|
|
238
|
+
chalker :task => 'chalk_it_good_baby'
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
Bumbleworks.launch!('chalking')
|
|
242
|
+
Bumbleworks.dashboard.wait_for(:chalker)
|
|
243
|
+
|
|
244
|
+
tasks = described_class.for_role('chalker')
|
|
245
|
+
tasks.map(&:nickname).should == [
|
|
246
|
+
'make_chalk_drawings',
|
|
247
|
+
'chalk_it_good_baby'
|
|
248
|
+
]
|
|
236
249
|
end
|
|
237
250
|
end
|
|
238
251
|
|
|
@@ -325,6 +338,39 @@ describe Bumbleworks::Task do
|
|
|
325
338
|
end
|
|
326
339
|
end
|
|
327
340
|
|
|
341
|
+
context '.for_entity' do
|
|
342
|
+
it 'returns all tasks associated with given entity' do
|
|
343
|
+
fake_sandwich = OpenStruct.new(:identifier => 'rubies')
|
|
344
|
+
Bumbleworks.define_process 'existential_pb_and_j' do
|
|
345
|
+
concurrence do
|
|
346
|
+
sandwich :task => 'be_made'
|
|
347
|
+
sandwich :task => 'contemplate_being'
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
Bumbleworks.launch!('existential_pb_and_j', :entity => fake_sandwich)
|
|
351
|
+
Bumbleworks.dashboard.wait_for(:sandwich)
|
|
352
|
+
tasks = described_class.for_entity(fake_sandwich)
|
|
353
|
+
tasks.should have(2).items
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
context '.by_nickname' do
|
|
358
|
+
it 'returns all tasks with given nickname' do
|
|
359
|
+
Bumbleworks.define_process 'animal_disagreements' do
|
|
360
|
+
concurrence do
|
|
361
|
+
turtle :task => 'be_a_big_jerk'
|
|
362
|
+
goose :task => 'punch_turtle'
|
|
363
|
+
rabbit :task => 'punch_turtle'
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
Bumbleworks.launch!('animal_disagreements')
|
|
367
|
+
Bumbleworks.dashboard.wait_for(:rabbit)
|
|
368
|
+
tasks = described_class.by_nickname('punch_turtle')
|
|
369
|
+
tasks.should have(2).items
|
|
370
|
+
tasks.map(&:role).should =~ ['goose', 'rabbit']
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
328
374
|
context 'claiming things' do
|
|
329
375
|
before :each do
|
|
330
376
|
Bumbleworks.define_process 'planting_a_noodle' do
|
|
@@ -337,7 +383,7 @@ describe Bumbleworks::Task do
|
|
|
337
383
|
end
|
|
338
384
|
|
|
339
385
|
describe '#claim' do
|
|
340
|
-
it 'sets token on
|
|
386
|
+
it 'sets token on "claimant" param' do
|
|
341
387
|
@task.params['claimant'].should == 'boss'
|
|
342
388
|
end
|
|
343
389
|
|
|
@@ -515,4 +561,92 @@ describe Bumbleworks::Task do
|
|
|
515
561
|
end
|
|
516
562
|
end
|
|
517
563
|
end
|
|
564
|
+
|
|
565
|
+
describe 'chained queries' do
|
|
566
|
+
it 'allows for AND-ed chained finders' do
|
|
567
|
+
Bumbleworks.define_process 'the_big_kachunko' do
|
|
568
|
+
concurrence do
|
|
569
|
+
red :task => 'be_really_mad'
|
|
570
|
+
blue :task => 'be_a_bit_sad'
|
|
571
|
+
yellow :task => 'be_scared'
|
|
572
|
+
green :task => 'be_envious'
|
|
573
|
+
green :task => 'be_proud'
|
|
574
|
+
pink :task => 'be_proud'
|
|
575
|
+
end
|
|
576
|
+
end
|
|
577
|
+
Bumbleworks.launch!('the_big_kachunko')
|
|
578
|
+
Bumbleworks.dashboard.wait_for(:pink)
|
|
579
|
+
described_class.by_nickname('be_really_mad').first.claim('crayon_box')
|
|
580
|
+
described_class.by_nickname('be_a_bit_sad').first.claim('crayon_box')
|
|
581
|
+
described_class.by_nickname('be_scared').first.claim('crayon_box')
|
|
582
|
+
|
|
583
|
+
tasks = described_class.
|
|
584
|
+
for_roles(['green', 'pink']).
|
|
585
|
+
by_nickname('be_proud')
|
|
586
|
+
tasks.should have(2).items
|
|
587
|
+
tasks.map(&:nickname).should =~ ['be_proud', 'be_proud']
|
|
588
|
+
|
|
589
|
+
tasks = described_class.
|
|
590
|
+
for_claimant('crayon_box').
|
|
591
|
+
for_roles(['red', 'yellow', 'green'])
|
|
592
|
+
tasks.should have(2).items
|
|
593
|
+
tasks.map(&:nickname).should =~ ['be_really_mad', 'be_scared']
|
|
594
|
+
|
|
595
|
+
tasks = described_class.
|
|
596
|
+
for_claimant('crayon_box').
|
|
597
|
+
by_nickname('be_a_bit_sad').
|
|
598
|
+
for_role('blue')
|
|
599
|
+
tasks.should have(1).item
|
|
600
|
+
tasks.first.nickname.should == 'be_a_bit_sad'
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
describe 'method missing' do
|
|
605
|
+
it 'calls method on new Finder object' do
|
|
606
|
+
described_class::Finder.any_instance.stub(:shabam!).with(:yay).and_return(:its_a_me)
|
|
607
|
+
described_class.shabam!(:yay).should == :its_a_me
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
it 'falls back to method missing if no finder method' do
|
|
611
|
+
expect {
|
|
612
|
+
described_class.kerplunk!(:oh_no)
|
|
613
|
+
}.to raise_error
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
describe '.next_available' do
|
|
618
|
+
it 'waits for one task to show up and returns it' do
|
|
619
|
+
Bumbleworks.define_process "lazy_bum_and_cool_guy" do
|
|
620
|
+
concurrence do
|
|
621
|
+
cool_guy :task => 'get_it_going_man'
|
|
622
|
+
sequence do
|
|
623
|
+
wait '2s'
|
|
624
|
+
bum :task => 'finally_get_a_round_tuit'
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
end
|
|
628
|
+
start_time = Time.now
|
|
629
|
+
Bumbleworks.launch!('lazy_bum_and_cool_guy')
|
|
630
|
+
task = described_class.for_role('bum').next_available
|
|
631
|
+
end_time = Time.now
|
|
632
|
+
task.nickname.should == 'finally_get_a_round_tuit'
|
|
633
|
+
(end_time - start_time).should >= 2
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
it 'times out if task does not appear in time' do
|
|
637
|
+
Bumbleworks.define_process "really_lazy_bum_and_cool_guy" do
|
|
638
|
+
concurrence do
|
|
639
|
+
cool_guy :task => 'good_golly_never_mind_you'
|
|
640
|
+
sequence do
|
|
641
|
+
wait '2s'
|
|
642
|
+
bum :task => 'whatever_these_socks_are_tasty'
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
end
|
|
646
|
+
Bumbleworks.launch!('really_lazy_bum_and_cool_guy')
|
|
647
|
+
expect {
|
|
648
|
+
described_class.for_role('bum').next_available(:timeout => 0.5)
|
|
649
|
+
}.to raise_error(Bumbleworks::Task::AvailabilityTimeout)
|
|
650
|
+
end
|
|
651
|
+
end
|
|
518
652
|
end
|
|
@@ -18,6 +18,11 @@ describe Bumbleworks::WorkitemEntityStorage do
|
|
|
18
18
|
feh.should have_entity_fields
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
it 'returns true if workitem fields include symbolized version of entity fields' do
|
|
22
|
+
feh = FakeEntityHolder.new(:entity_id => '1', :entity_type => 'SomeEntity')
|
|
23
|
+
feh.should have_entity_fields
|
|
24
|
+
end
|
|
25
|
+
|
|
21
26
|
it 'returns false if workitem fields do not include entity fields' do
|
|
22
27
|
feh = FakeEntityHolder.new
|
|
23
28
|
feh.should_not have_entity_fields
|
|
@@ -62,6 +67,11 @@ describe Bumbleworks::WorkitemEntityStorage do
|
|
|
62
67
|
feh.entity.identifier.should == '15'
|
|
63
68
|
end
|
|
64
69
|
|
|
70
|
+
it 'works with symbolized _id and _type fields' do
|
|
71
|
+
feh = FakeEntityHolder.new(:entity_id => '15', :entity_type => 'LovelyEntity')
|
|
72
|
+
feh.entity.identifier.should == '15'
|
|
73
|
+
end
|
|
74
|
+
|
|
65
75
|
it 'throw exception if entity fields not present' do
|
|
66
76
|
feh = FakeEntityHolder.new
|
|
67
77
|
expect {
|
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.26
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -178,6 +178,7 @@ files:
|
|
|
178
178
|
- lib/bumbleworks/storage_participant.rb
|
|
179
179
|
- lib/bumbleworks/support.rb
|
|
180
180
|
- lib/bumbleworks/task.rb
|
|
181
|
+
- lib/bumbleworks/task/finder.rb
|
|
181
182
|
- lib/bumbleworks/tasks/base.rb
|
|
182
183
|
- lib/bumbleworks/tree_builder.rb
|
|
183
184
|
- lib/bumbleworks/version.rb
|
|
@@ -227,18 +228,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
227
228
|
- - ! '>='
|
|
228
229
|
- !ruby/object:Gem::Version
|
|
229
230
|
version: '0'
|
|
230
|
-
segments:
|
|
231
|
-
- 0
|
|
232
|
-
hash: -2155630126504321546
|
|
233
231
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
234
232
|
none: false
|
|
235
233
|
requirements:
|
|
236
234
|
- - ! '>='
|
|
237
235
|
- !ruby/object:Gem::Version
|
|
238
236
|
version: '0'
|
|
239
|
-
segments:
|
|
240
|
-
- 0
|
|
241
|
-
hash: -2155630126504321546
|
|
242
237
|
requirements: []
|
|
243
238
|
rubyforge_project:
|
|
244
239
|
rubygems_version: 1.8.23
|
|
@@ -277,3 +272,4 @@ test_files:
|
|
|
277
272
|
- spec/lib/bumbleworks_spec.rb
|
|
278
273
|
- spec/spec_helper.rb
|
|
279
274
|
- spec/support/path_helpers.rb
|
|
275
|
+
has_rdoc:
|