bumbleworks 0.0.81 → 0.0.82

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: ba5107c8d92ddb8478fb30368178febaf26f6a0d
4
- data.tar.gz: 845838859128ba26395fd1da45b4938051885123
3
+ metadata.gz: 804829e3161fb2670468286592f615f6fea68d0f
4
+ data.tar.gz: 9dcb8fb16e7e379630b6f7a782c298f652cbdab2
5
5
  SHA512:
6
- metadata.gz: e8bb0121ed0b8216b4499ac35f281c29bf74b686caf0a3dbd8b80cb2e923ed3a864a1be95d9e822fbb67e0a5c140a63b6818a3f7d0227759bc8959588ddcfbda
7
- data.tar.gz: 744f4cf5217a6fe39b414feb2aa2eb3daabfb54469f9fc1533edd210866d3080a76a75f9aceebf0b92ded794cc122eea46e5b186d144fd3c73ee984e7ecabd35
6
+ metadata.gz: c8754753a28d8a68cdc8684f752425591e2ca7da29213b2ade253f63471a9d7cab24aef4799d0841b5d29f13073f169f7985590198da69476fab6190fac33dc4
7
+ data.tar.gz: b45afd4311dd8a2ba30dea2229abd7467063a60535294f7eabe196aef2b3980851ec77548988ca34b532bab4bf895bcff7c79dbb6c992d19e9c2c842a1ef3154
@@ -48,7 +48,6 @@ module Bumbleworks
48
48
  end
49
49
 
50
50
  def cancel_process!(wfid, options = {})
51
- options[:timeout] ||= Bumbleworks.timeout
52
51
  unless options[:method] == :kill
53
52
  options[:method] = :cancel
54
53
  end
@@ -59,14 +58,12 @@ module Bumbleworks
59
58
  storage.remove_process(wfid)
60
59
  end
61
60
 
62
- start_time = Time.now
63
- while dashboard.process(wfid)
64
- if (Time.now - start_time) > options[:timeout]
65
- error_type = options[:method] == :cancel ? CancelTimeout : KillTimeout
66
- raise error_type, "Process #{options[:method]} for wfid '#{wfid}' taking too long. Errors: #{dashboard.errors(wfid)}"
67
- end
68
- sleep 0.1
61
+ Bumbleworks::Support.wait_until(options) do
62
+ dashboard.process(wfid).nil?
69
63
  end
64
+ rescue Bumbleworks::Support::WaitTimeout
65
+ error_type = options[:method] == :cancel ? CancelTimeout : KillTimeout
66
+ raise error_type, "Process #{options[:method]} for wfid '#{wfid}' taking too long. Errors: #{dashboard.errors(wfid)}"
70
67
  end
71
68
 
72
69
  def kill_process!(wfid, options = {})
@@ -74,15 +71,13 @@ module Bumbleworks
74
71
  end
75
72
 
76
73
  def cancel_all_processes!(options = {})
77
- options[:timeout] ||= Bumbleworks.timeout
78
74
  unless options[:method] == :kill
79
75
  options[:method] = :cancel
80
76
  end
81
77
 
82
78
  notified_process_wfids = []
83
79
 
84
- start_time = Time.now
85
- while dashboard.process_wfids.count > 0
80
+ Bumbleworks::Support.wait_until(options) do
86
81
  new_process_wfids = dashboard.process_wfids - notified_process_wfids
87
82
  if options[:method] == :cancel || !options[:force]
88
83
  send_cancellation_message(options[:method], new_process_wfids)
@@ -90,13 +85,11 @@ module Bumbleworks
90
85
  storage.clear
91
86
  end
92
87
  notified_process_wfids += new_process_wfids
93
-
94
- if (Time.now - start_time) > options[:timeout]
95
- error_type = options[:method] == :cancel ? CancelTimeout : KillTimeout
96
- raise error_type, "Process #{options[:method]} taking too long - #{dashboard.process_wfids.count} processes remain. Errors: #{dashboard.errors}"
97
- end
98
- sleep 0.1
88
+ dashboard.process_wfids.count == 0
99
89
  end
90
+ rescue Bumbleworks::Support::WaitTimeout
91
+ error_type = options[:method] == :cancel ? CancelTimeout : KillTimeout
92
+ raise error_type, "Process #{options[:method]} taking too long - #{dashboard.process_wfids.count} processes remain. Errors: #{dashboard.errors}"
100
93
  end
101
94
 
102
95
  def send_cancellation_message(method, process_wfids)
@@ -3,6 +3,7 @@ module Bumbleworks
3
3
  # could also be accomplished by monkey-patching String class.
4
4
  module Support
5
5
  module_function
6
+ class WaitTimeout < StandardError; end
6
7
 
7
8
  def camelize(string)
8
9
  string = string.sub(/^[a-z\d]*/) { $&.capitalize }
@@ -50,5 +51,16 @@ module Bumbleworks
50
51
  return nil if string.nil?
51
52
  humanize(string).gsub(/\b('?[a-z])/) { $1.capitalize }
52
53
  end
54
+
55
+ def wait_until(options = {}, &block)
56
+ options[:timeout] ||= Bumbleworks.timeout
57
+ start_time = Time.now
58
+ until block.call
59
+ if (Time.now - start_time) > options[:timeout]
60
+ raise WaitTimeout
61
+ end
62
+ sleep 0.1
63
+ end
64
+ end
53
65
  end
54
66
  end
@@ -1,3 +1,3 @@
1
1
  module Bumbleworks
2
- VERSION = "0.0.81"
2
+ VERSION = "0.0.82"
3
3
  end
@@ -55,18 +55,26 @@ class Bumbleworks::Worker < Ruote::Worker
55
55
  end
56
56
 
57
57
  def change_worker_state(new_state, options = {})
58
- options[:timeout] ||= Bumbleworks.timeout
59
58
  with_worker_state_enabled do
60
59
  Bumbleworks.dashboard.worker_state = new_state
61
- start_time = Time.now
62
- until worker_states.values.all? { |state| state == new_state }
63
- if (Time.now - start_time) > options[:timeout]
64
- raise WorkerStateNotChanged, "Worker states: #{worker_states.inspect}"
65
- end
66
- sleep 0.1
60
+ Bumbleworks::Support.wait_until(options) do
61
+ worker_states.values.all? { |state| state == new_state }
67
62
  end
68
63
  end
69
64
  return true
65
+ rescue Bumbleworks::Support::WaitTimeout
66
+ raise WorkerStateNotChanged, "Worker states: #{worker_states.inspect}"
67
+ end
68
+
69
+ def refresh_worker_info(options = {})
70
+ with_worker_state_enabled do
71
+ Bumbleworks::Support.wait_until(options) do
72
+ info.all? { |id, worker_info|
73
+ worker_info['state'] == 'stopped' ||
74
+ Time.parse(worker_info['put_at']) > Time.now - 1
75
+ }
76
+ end
77
+ end
70
78
  end
71
79
 
72
80
  def with_worker_state_enabled
@@ -86,7 +94,7 @@ class Bumbleworks::Worker < Ruote::Worker
86
94
  end
87
95
 
88
96
  def save_info
89
- @info.save_with_cleanup if @info
97
+ @info.save if @info
90
98
  end
91
99
 
92
100
  def shutdown
@@ -101,34 +109,56 @@ class Bumbleworks::Worker < Ruote::Worker
101
109
  end
102
110
  end
103
111
 
112
+ def info
113
+ self.class.info[id]
114
+ end
115
+
104
116
  class Info < Ruote::Worker::Info
105
- def <<(msg)
106
- last_save = @last_save
107
- super
108
- cleanup_saved_info if Time.now > last_save + 60
109
- end
117
+ def save
118
+ doc = @worker.storage.get('variables', 'workers') || {}
110
119
 
111
- def save_with_cleanup
112
- save
113
- cleanup_saved_info
114
- end
120
+ doc['type'] = 'variables'
121
+ doc['_id'] = 'workers'
115
122
 
116
- def cleanup_saved_info
117
- key = [@worker.name, @ip.gsub(/\./, '_'), $$.to_s].join('/')
118
- doc = @worker.storage.get('variables', 'workers')
119
- existing_worker_info = doc['workers'].delete(key)
120
- if existing_worker_info
121
- doc['workers'][@worker.id] = existing_worker_info.merge({
122
- 'state' => @worker.state,
123
- 'name' => @worker.name
124
- })
125
- result = @worker.storage.put(doc)
126
- # result will be nil if put succeeded; if it's not,
127
- # let's try again
128
- cleanup_saved_info if result
129
- else
130
- cleanup_saved_info
131
- end
123
+ now = Time.now
124
+
125
+ @msgs = @msgs.drop_while { |msg|
126
+ Time.parse(msg['processed_at']) < now - 3600
127
+ }
128
+ mm = @msgs.drop_while { |msg|
129
+ Time.parse(msg['processed_at']) < now - 60
130
+ }
131
+
132
+ hour_count = @msgs.size < 1 ? 1 : @msgs.size
133
+ minute_count = mm.size < 1 ? 1 : mm.size
134
+
135
+ (doc['workers'] ||= {})[@worker.id] = {
136
+
137
+ 'class' => @worker.class.to_s,
138
+ 'name' => @worker.name,
139
+ 'ip' => @ip,
140
+ 'hostname' => @hostname,
141
+ 'pid' => $$,
142
+ 'system' => @system,
143
+ 'put_at' => Ruote.now_to_utc_s,
144
+ 'uptime' => Time.now - @since,
145
+ 'state' => @worker.state,
146
+
147
+ 'processed_last_minute' =>
148
+ mm.size,
149
+ 'wait_time_last_minute' =>
150
+ mm.inject(0.0) { |s, m| s + m['wait_time'] } / minute_count.to_f,
151
+ 'processed_last_hour' =>
152
+ @msgs.size,
153
+ 'wait_time_last_hour' =>
154
+ @msgs.inject(0.0) { |s, m| s + m['wait_time'] } / hour_count.to_f
155
+ }
156
+
157
+ r = @worker.storage.put(doc)
158
+
159
+ @last_save = Time.now
160
+
161
+ save if r != nil
132
162
  end
133
163
  end
134
164
  end
@@ -38,7 +38,7 @@ describe Bumbleworks::Worker do
38
38
  subject.run_in_thread
39
39
  workers[0].shutdown
40
40
  workers[1].instance_variable_set(:@state, nil)
41
- workers[1].instance_variable_get(:@info).save_with_cleanup
41
+ workers[1].instance_variable_get(:@info).save
42
42
  expect(described_class.worker_states).to eq({
43
43
  subject.id => 'running'
44
44
  })
@@ -59,12 +59,32 @@ describe Bumbleworks::Worker do
59
59
  end
60
60
  end
61
61
 
62
+ describe '.refresh_worker_info' do
63
+ it 'times out if info is not updated in time' do
64
+ allow(described_class).to receive(:info).and_return({
65
+ :dummy_id => { 'put_at' => (Time.now - 60).to_s }
66
+ })
67
+ expect {
68
+ described_class.refresh_worker_info(:timeout => 0.1)
69
+ }.to raise_error(Bumbleworks::Support::WaitTimeout)
70
+ end
71
+
72
+ it 'refreshes worker info' do
73
+ subject.run_in_thread
74
+ doc = subject.storage.get('variables', 'workers')
75
+ doc['workers'][subject.id]['put_at'] = (Time.now - 30).to_s
76
+ subject.storage.put(doc)
77
+ described_class.refresh_worker_info
78
+ expect(Time.parse(subject.info['put_at'])).to be_within(1).of(Time.now)
79
+ end
80
+ end
81
+
62
82
  describe '.purge_stale_worker_info' do
63
83
  it 'deletes all worker info where state is stopped or nil' do
64
84
  subject.run_in_thread
65
85
  workers[0].shutdown
66
86
  workers[1].instance_variable_set(:@state, nil)
67
- workers[1].instance_variable_get(:@info).save_with_cleanup
87
+ workers[1].instance_variable_get(:@info).save
68
88
  subject_info = described_class.info[subject.id]
69
89
  described_class.purge_stale_worker_info
70
90
  expect(described_class.info).to eq({
@@ -125,4 +145,10 @@ describe Bumbleworks::Worker do
125
145
  expect(subject.id).to eq('smokeeeeys')
126
146
  end
127
147
  end
148
+
149
+ describe '#info' do
150
+ it 'returns worker info for worker id' do
151
+ expect(subject.info).to eq(described_class.info[subject.id])
152
+ end
153
+ end
128
154
  end
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.81
4
+ version: 0.0.82
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maher Hawash