bumbleworks 0.0.78 → 0.0.79
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 +4 -4
- data/lib/bumbleworks/ruote.rb +2 -1
- data/lib/bumbleworks/version.rb +1 -1
- data/lib/bumbleworks/worker.rb +133 -0
- data/spec/lib/bumbleworks/ruote_spec.rb +3 -3
- data/spec/lib/bumbleworks/worker_spec.rb +130 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4318f91e073ccdd49dc2cd628c7f93991e2214da
|
4
|
+
data.tar.gz: 529b85a2177008687c9bfb0bba2abbb0b00be213
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b47f0e5543948f413dc6b83bd368db1685ddc5d1fbc6a399e2f2ff0d5d40a92bbb7c92ba9b32d3ccace51915251369ba9fa4095c2af5826711d8a5100e8c5751
|
7
|
+
data.tar.gz: c9b44b6f6dd055b8f0afa70f2d7d8161b6b6654cfae1cb335a865ed170f6d0ed2dd8b9f2d4674eb40402677d19ec2395af56eeb941c361163ca8c1558bd1d0ad
|
data/lib/bumbleworks/ruote.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "ruote"
|
2
|
+
require_relative "worker.rb"
|
2
3
|
|
3
4
|
Dir[File.join(File.dirname(__FILE__), 'ruote', 'exp', '*.rb')].each { |f| require f }
|
4
5
|
|
@@ -31,7 +32,7 @@ module Bumbleworks
|
|
31
32
|
set_up_storage_history
|
32
33
|
register_error_dispatcher
|
33
34
|
dashboard.noisy = options[:verbose] == true
|
34
|
-
worker = ::
|
35
|
+
worker = Bumbleworks::Worker.new(dashboard.context)
|
35
36
|
if options[:join] == true
|
36
37
|
worker.run
|
37
38
|
else
|
data/lib/bumbleworks/version.rb
CHANGED
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
class Bumbleworks::Worker < Ruote::Worker
|
4
|
+
class WorkerStateNotChanged < StandardError; end
|
5
|
+
|
6
|
+
attr_reader :id
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def info
|
10
|
+
Bumbleworks.dashboard.worker_info
|
11
|
+
end
|
12
|
+
|
13
|
+
def shutdown_all(options = {})
|
14
|
+
change_worker_state('stopped', options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def pause_all(options = {})
|
18
|
+
change_worker_state('paused', options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def unpause_all(options = {})
|
22
|
+
change_worker_state('running', options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def worker_states
|
26
|
+
Bumbleworks.dashboard.worker_info.inject({}) { |hsh, info|
|
27
|
+
id, state = info[0], info[1]['state']
|
28
|
+
if state && state != 'stopped'
|
29
|
+
hsh[id] = state
|
30
|
+
end
|
31
|
+
hsh
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def forget_worker(id_to_delete)
|
36
|
+
purge_worker_info do |id, info|
|
37
|
+
id == id_to_delete
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def purge_stale_worker_info
|
42
|
+
purge_worker_info do |id, info|
|
43
|
+
info['state'].nil? || info['state'] == 'stopped'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def purge_worker_info(&block)
|
48
|
+
doc = Bumbleworks.dashboard.storage.get('variables', 'workers')
|
49
|
+
doc['workers'] = doc['workers'].reject { |id, info|
|
50
|
+
block.call(id, info)
|
51
|
+
}
|
52
|
+
result = Bumbleworks.dashboard.storage.put(doc)
|
53
|
+
purge_stale_worker_info if result
|
54
|
+
info
|
55
|
+
end
|
56
|
+
|
57
|
+
def change_worker_state(new_state, options = {})
|
58
|
+
options[:timeout] ||= Bumbleworks.timeout
|
59
|
+
with_worker_state_enabled do
|
60
|
+
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
|
67
|
+
end
|
68
|
+
end
|
69
|
+
return true
|
70
|
+
end
|
71
|
+
|
72
|
+
def with_worker_state_enabled
|
73
|
+
Bumbleworks.dashboard.context['worker_state_enabled'] = true
|
74
|
+
yield
|
75
|
+
Bumbleworks.dashboard.context['worker_state_enabled'] = false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def initialize(*args, &block)
|
80
|
+
super
|
81
|
+
@id = SecureRandom.uuid
|
82
|
+
if @info
|
83
|
+
@info = Info.new(self)
|
84
|
+
save_info
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def save_info
|
89
|
+
@info.save_with_cleanup if @info
|
90
|
+
end
|
91
|
+
|
92
|
+
def shutdown
|
93
|
+
super
|
94
|
+
save_info
|
95
|
+
end
|
96
|
+
|
97
|
+
def determine_state
|
98
|
+
if @context['worker_state_enabled']
|
99
|
+
super
|
100
|
+
save_info
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class Info < Ruote::Worker::Info
|
105
|
+
def <<(msg)
|
106
|
+
super
|
107
|
+
cleanup_saved_info if Time.now > @last_save + 60
|
108
|
+
end
|
109
|
+
|
110
|
+
def save_with_cleanup
|
111
|
+
save
|
112
|
+
cleanup_saved_info
|
113
|
+
end
|
114
|
+
|
115
|
+
def cleanup_saved_info
|
116
|
+
key = [@worker.name, @ip.gsub(/\./, '_'), $$.to_s].join('/')
|
117
|
+
doc = @worker.storage.get('variables', 'workers')
|
118
|
+
existing_worker_info = doc['workers'].delete(key)
|
119
|
+
if existing_worker_info
|
120
|
+
doc['workers'][@worker.id] = existing_worker_info.merge({
|
121
|
+
'state' => @worker.state,
|
122
|
+
'name' => @worker.name
|
123
|
+
})
|
124
|
+
result = @worker.storage.put(doc)
|
125
|
+
# result will be nil if put succeeded; if it's not,
|
126
|
+
# let's try again
|
127
|
+
cleanup_saved_info if result
|
128
|
+
else
|
129
|
+
cleanup_saved_info
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -218,18 +218,18 @@ describe Bumbleworks::Ruote do
|
|
218
218
|
it 'adds new worker to dashboard and returns worker' do
|
219
219
|
expect(described_class.dashboard.worker).to be_nil
|
220
220
|
new_worker = described_class.start_worker!
|
221
|
-
expect(new_worker).to be_an_instance_of(
|
221
|
+
expect(new_worker).to be_an_instance_of(Bumbleworks::Worker)
|
222
222
|
expect(described_class.dashboard.worker).to eq(new_worker)
|
223
223
|
end
|
224
224
|
|
225
225
|
it 'runs in current thread if :join option is true' do
|
226
|
-
allow(::
|
226
|
+
allow(Bumbleworks::Worker).to receive(:new).and_return(worker_double = double('worker'))
|
227
227
|
expect(worker_double).to receive(:run)
|
228
228
|
described_class.start_worker!(:join => true)
|
229
229
|
end
|
230
230
|
|
231
231
|
it 'runs in new thread and returns worker if :join option not true' do
|
232
|
-
allow(::
|
232
|
+
allow(Bumbleworks::Worker).to receive(:new).and_return(worker_double = double('worker'))
|
233
233
|
expect(worker_double).to receive(:run_in_thread)
|
234
234
|
expect(described_class.start_worker!).to eq(worker_double)
|
235
235
|
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'pry'
|
2
|
+
|
3
|
+
describe Bumbleworks::Worker do
|
4
|
+
let(:context) { Bumbleworks.dashboard.context }
|
5
|
+
subject { described_class.new(context) }
|
6
|
+
|
7
|
+
it 'is a Ruote::Worker' do
|
8
|
+
expect(subject).to be_a(Ruote::Worker)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.new' do
|
12
|
+
it 'saves the worker info to a storage variable' do
|
13
|
+
subject
|
14
|
+
workers = Bumbleworks.dashboard.worker_info
|
15
|
+
expect(workers.count).to eq(1)
|
16
|
+
expect(workers.keys.first).to eq(subject.id)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with multiple workers' do
|
21
|
+
let!(:workers) {
|
22
|
+
2.times.map { |i|
|
23
|
+
worker = described_class.new(context)
|
24
|
+
worker.run_in_thread
|
25
|
+
worker
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
describe '.worker_states' do
|
30
|
+
it 'returns the states of all active workers' do
|
31
|
+
subject.run_in_thread
|
32
|
+
expect(described_class.worker_states).to eq({
|
33
|
+
subject.id => 'running',
|
34
|
+
workers[0].id => 'running',
|
35
|
+
workers[1].id => 'running'
|
36
|
+
})
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'does not include stopped or nil states' do
|
40
|
+
subject.run_in_thread
|
41
|
+
workers[0].shutdown
|
42
|
+
workers[1].instance_variable_set(:@state, nil)
|
43
|
+
workers[1].instance_variable_get(:@info).save_with_cleanup
|
44
|
+
expect(described_class.worker_states).to eq({
|
45
|
+
subject.id => 'running'
|
46
|
+
})
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '.info' do
|
51
|
+
it 'returns Bumbleworks.dashboard.worker_info' do
|
52
|
+
allow(Bumbleworks.dashboard).to receive(:worker_info).and_return(:bontron)
|
53
|
+
expect(described_class.info).to eq(:bontron)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '.forget_worker' do
|
58
|
+
it 'deletes worker info for given worker id' do
|
59
|
+
described_class.forget_worker(workers[1].id)
|
60
|
+
expect(described_class.info.keys).not_to include(workers[1].id)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '.purge_stale_worker_info' do
|
65
|
+
it 'deletes all worker info where state is stopped or nil' do
|
66
|
+
subject.run_in_thread
|
67
|
+
workers[0].shutdown
|
68
|
+
workers[1].instance_variable_set(:@state, nil)
|
69
|
+
workers[1].instance_variable_get(:@info).save_with_cleanup
|
70
|
+
subject_info = described_class.info[subject.id]
|
71
|
+
described_class.purge_stale_worker_info
|
72
|
+
expect(described_class.info).to eq({
|
73
|
+
subject.id => subject_info
|
74
|
+
})
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '.change_worker_state' do
|
79
|
+
it 'changes state of all workers' do
|
80
|
+
expect(workers.map(&:state).uniq).to eq(['running'])
|
81
|
+
described_class.change_worker_state('paused')
|
82
|
+
expect(workers.map(&:state).uniq).to eq(['paused'])
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'times out if worker states not changed in time' do
|
86
|
+
# Stub setting of worker state so workers are never stopped
|
87
|
+
allow(Bumbleworks.dashboard).to receive(:worker_state=)
|
88
|
+
expect {
|
89
|
+
described_class.change_worker_state('paused', :timeout => 0)
|
90
|
+
}.to raise_error(described_class::WorkerStateNotChanged)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'ignores already stopped workers' do
|
94
|
+
described_class.shutdown_all
|
95
|
+
subject.run_in_thread
|
96
|
+
described_class.change_worker_state('paused')
|
97
|
+
expect(subject.state).to eq('paused')
|
98
|
+
expect(workers.map(&:state)).to eq(['stopped', 'stopped'])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '.shutdown_all' do
|
104
|
+
it 'changes all worker states to stopped' do
|
105
|
+
expect(described_class).to receive(:change_worker_state).with('stopped', {})
|
106
|
+
described_class.shutdown_all
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '.pause_all' do
|
111
|
+
it 'changes all worker states to paused' do
|
112
|
+
expect(described_class).to receive(:change_worker_state).with('paused', {})
|
113
|
+
described_class.pause_all
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '.unpause_all' do
|
118
|
+
it 'changes all worker states to running' do
|
119
|
+
expect(described_class).to receive(:change_worker_state).with('running', {})
|
120
|
+
described_class.unpause_all
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '#id' do
|
125
|
+
it 'returns generated uuid' do
|
126
|
+
allow(SecureRandom).to receive(:uuid).and_return('smokeeeeys')
|
127
|
+
expect(subject.id).to eq('smokeeeeys')
|
128
|
+
end
|
129
|
+
end
|
130
|
+
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.
|
4
|
+
version: 0.0.79
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maher Hawash
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2014-08-
|
14
|
+
date: 2014-08-10 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: ruote
|
@@ -181,6 +181,7 @@ files:
|
|
181
181
|
- lib/bumbleworks/tree_builder.rb
|
182
182
|
- lib/bumbleworks/user.rb
|
183
183
|
- lib/bumbleworks/version.rb
|
184
|
+
- lib/bumbleworks/worker.rb
|
184
185
|
- lib/bumbleworks/workitem.rb
|
185
186
|
- lib/bumbleworks/workitem_entity_storage.rb
|
186
187
|
- lib/tasks/bumbleworks.rake
|
@@ -234,6 +235,7 @@ files:
|
|
234
235
|
- spec/lib/bumbleworks/tracker_spec.rb
|
235
236
|
- spec/lib/bumbleworks/tree_builder_spec.rb
|
236
237
|
- spec/lib/bumbleworks/user_spec.rb
|
238
|
+
- spec/lib/bumbleworks/worker_spec.rb
|
237
239
|
- spec/lib/bumbleworks/workitem_entity_storage_spec.rb
|
238
240
|
- spec/lib/bumbleworks/workitem_spec.rb
|
239
241
|
- spec/lib/bumbleworks_spec.rb
|
@@ -317,6 +319,7 @@ test_files:
|
|
317
319
|
- spec/lib/bumbleworks/tracker_spec.rb
|
318
320
|
- spec/lib/bumbleworks/tree_builder_spec.rb
|
319
321
|
- spec/lib/bumbleworks/user_spec.rb
|
322
|
+
- spec/lib/bumbleworks/worker_spec.rb
|
320
323
|
- spec/lib/bumbleworks/workitem_entity_storage_spec.rb
|
321
324
|
- spec/lib/bumbleworks/workitem_spec.rb
|
322
325
|
- spec/lib/bumbleworks_spec.rb
|