bumbleworks 0.0.32 → 0.0.33

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.
@@ -43,6 +43,27 @@ module Bumbleworks
43
43
  dashboard.launch(dashboard.variables[name], *args)
44
44
  end
45
45
 
46
+ def cancel_process!(wfid, options = {})
47
+ options[:timeout] ||= 5
48
+ unless options[:method] == :kill
49
+ options[:method] = :cancel
50
+ end
51
+
52
+ dashboard.send(options[:method], wfid)
53
+ start_time = Time.now
54
+ while dashboard.process(wfid)
55
+ if (Time.now - start_time) > options[:timeout]
56
+ error_type = options[:method] == :cancel ? CancelTimeout : KillTimeout
57
+ raise error_type, "Process #{options[:method]} taking too long - #{dashboard.processes.count} processes remain. Errors: #{dashboard.errors}"
58
+ end
59
+ sleep 0.1
60
+ end
61
+ end
62
+
63
+ def kill_process!(wfid, options = {})
64
+ cancel_process!(wfid, options.merge(:method => :kill))
65
+ end
66
+
46
67
  def cancel_all_processes!(options = {})
47
68
  options[:timeout] ||= 5
48
69
  unless options[:method] == :kill
@@ -5,6 +5,11 @@ module Ruote::Exp
5
5
  class WaitForEventExpression < AwaitExpression
6
6
  names :wait_for_event
7
7
 
8
+ # This does the same as the base AwaitExpression#apply, except that this
9
+ # will always be a global listener, listening for a 'left_tag' event, and
10
+ # the event's workitem will be discarded after the reply is complete. The
11
+ # event's workitem is only used for comparisons in the where clause (see
12
+ # #reply).
8
13
  def apply
9
14
  update_tree
10
15
  h.updated_tree[1]['global'] = true
@@ -13,14 +18,29 @@ module Ruote::Exp
13
18
  super
14
19
  end
15
20
 
21
+ # On apply, the workitem for this FlowExpression was replaced by the workitem
22
+ # from the event. So when we refer to "f:" in this #reply method, we're
23
+ # looking at the event's workitem, which will be discarded at the end of this
24
+ # reply (and replaced with the applied workitem). In order to compare the
25
+ # event's workitem with the applied workitem (so we can determine whether or
26
+ # not the event was intended for us), we assign the applied_workitem's fields
27
+ # to a hash on the event's workitem fields, available at "f:receiver.*".
16
28
  def reply(workitem)
17
29
  update_tree
30
+ # If we have a where clause at all...
18
31
  if translated_where = attribute(:where, nil, :escape => true)
19
32
  if translated_where.to_s == 'entities_match'
33
+ # Check to see that the event's entity is equal to the current workitem's
34
+ # entity. If so, this message is intended for us.
20
35
  translated_where = '${f:entity_id} == ${f:receiver.entity_id} && ${f:entity_type} == ${f:receiver.entity_type}'
21
36
  else
22
- translated_where.gsub!('${event:', '${f:')
23
- translated_where.gsub!('${this:', '${f:receiver.')
37
+ # This just gives us a shortcut so the process definition reads more
38
+ # clearly. You could always use "${f:" and "${f:receiver." in your
39
+ # where clauses, but you have to remember that the former refers to the
40
+ # incoming event's workitem, and the latter is the workitem of the
41
+ # listening process.
42
+ translated_where.gsub!('${event:', '${f:') # event workitem
43
+ translated_where.gsub!('${this:', '${f:receiver.') # listening workitem
24
44
  end
25
45
  h.updated_tree[1]['where'] = translated_where
26
46
  end
@@ -1,3 +1,3 @@
1
1
  module Bumbleworks
2
- VERSION = "0.0.32"
2
+ VERSION = "0.0.33"
3
3
  end
@@ -4,6 +4,70 @@ describe Bumbleworks::Ruote do
4
4
  Bumbleworks.storage = {}
5
5
  end
6
6
 
7
+ describe ".cancel_process!" do
8
+ before :each do
9
+ Bumbleworks.start_worker!
10
+ end
11
+
12
+ it 'cancels given process' do
13
+ Bumbleworks.define_process 'do_nothing' do
14
+ lazy_guy :task => 'absolutely_nothing'
15
+ end
16
+ wfid = Bumbleworks.launch!('do_nothing')
17
+ Bumbleworks.dashboard.wait_for(:lazy_guy)
18
+ Bumbleworks.dashboard.process(wfid).should_not be_nil
19
+ described_class.cancel_process!(wfid)
20
+ Bumbleworks.dashboard.process(wfid).should be_nil
21
+ end
22
+
23
+ it 'times out if process is not cancelled in time' do
24
+ Bumbleworks.define_process "time_hog" do
25
+ sequence :on_cancel => 'ignore_parents' do
26
+ pigheaded :task => 'whatever'
27
+ end
28
+ define 'ignore_parents' do
29
+ wait '1s'
30
+ end
31
+ end
32
+ wfid = Bumbleworks.launch!('time_hog')
33
+ Bumbleworks.dashboard.wait_for(:pigheaded)
34
+ Bumbleworks.dashboard.process(wfid).should_not be_nil
35
+ expect {
36
+ described_class.cancel_process!(wfid, :timeout => 0.5)
37
+ }.to raise_error(Bumbleworks::Ruote::CancelTimeout)
38
+ end
39
+ end
40
+
41
+ describe ".kill_process!" do
42
+ before :each do
43
+ Bumbleworks.start_worker!
44
+ end
45
+
46
+ it 'kills given process without running on_cancel' do
47
+ Bumbleworks.define_process "do_nothing" do
48
+ sequence :on_cancel => 'rethink_life' do
49
+ lazy_guy :task => 'absolutely_nothing'
50
+ end
51
+ define 'rethink_life' do
52
+ wait '10s'
53
+ end
54
+ end
55
+ wfid = Bumbleworks.launch!('do_nothing')
56
+ Bumbleworks.dashboard.wait_for(:lazy_guy)
57
+ Bumbleworks.dashboard.process(wfid).should_not be_nil
58
+ described_class.kill_process!(wfid)
59
+ Bumbleworks.dashboard.process(wfid).should be_nil
60
+ end
61
+
62
+ it 'times out if process is not killed in time' do
63
+ Bumbleworks.dashboard.stub(:kill)
64
+ Bumbleworks.dashboard.stub(:process).with('woot').and_return(:i_exist)
65
+ expect {
66
+ described_class.kill_process!('woot', :timeout => 0.5)
67
+ }.to raise_error(Bumbleworks::Ruote::KillTimeout)
68
+ end
69
+ end
70
+
7
71
  describe ".cancel_all_processes!" do
8
72
  before :each do
9
73
  Bumbleworks::Ruote.register_participants
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.32
4
+ version: 0.0.33
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-13 00:00:00.000000000 Z
15
+ date: 2013-08-21 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: ruote