bumbleworks 0.0.34 → 0.0.35

Sign up to get free protection for your applications and to get access to all the features.
@@ -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!
@@ -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
- before_update(metadata)
97
- update_workitem
98
- log(:update, metadata)
99
- after_update(metadata)
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
- before_update(metadata)
106
- before_complete(metadata)
107
- proceed_workitem
108
- log(:complete, metadata)
109
- after_complete(metadata)
110
- after_update(metadata)
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
- before_claim(token)
126
- set_claimant(token)
127
- log(:claim)
128
- after_claim(token)
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
- before_release(current_claimant)
140
- log(:release)
141
- set_claimant(nil)
142
- after_release(current_claimant)
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
- after_dispatch
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 Bumbleworks::Task::AvailabilityTimeout, "No tasks found matching criteria in time"
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
- Task.new(wi) if wi.params['task']
81
+ @task_class.new(wi) if wi.params['task']
72
82
  }.compact
73
83
  end
74
84
  end
@@ -1,3 +1,3 @@
1
1
  module Bumbleworks
2
- VERSION = "0.0.34"
2
+ VERSION = "0.0.35"
3
3
  end
@@ -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, and triggers callback' do
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 after_dispatch callback' do
122
+ it 'calls after hooks' do
109
123
  task = described_class.new(workflow_item)
110
124
  task.stub(:log)
111
- task.should_receive(:after_dispatch)
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 before_release and after_release callbacks' do
475
- @task.should_receive(:before_release).with('boss').ordered
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(:after_release).with('boss').ordered
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 before_update and after_update callbacks' do
578
+ it 'calls with hooks' do
512
579
  task = described_class.new(workflow_item)
513
580
  task.stub(:log)
514
- task.should_receive(:before_update).with(:argue_mints).ordered
581
+ task.should_receive(:call_before_hooks).with(:update, :argue_mints).ordered
515
582
  task.should_receive(:update_workitem).ordered
516
- task.should_receive(:after_update).with(:argue_mints).ordered
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(:before_update).with(:argue_mints).ordered
574
- task.should_receive(:before_complete).with(:argue_mints).ordered
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(:after_complete).with(:argue_mints).ordered
577
- task.should_receive(:after_update).with(:argue_mints).ordered
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.34
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-08-21 00:00:00.000000000 Z
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: