rabbitmq-cluster 0.0.6 → 0.0.7
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/Rakefile +1 -0
- data/bin/rabbitmq-cluster +1 -1
- data/lib/rabbitmq/cluster/etcd.rb +4 -7
- data/lib/rabbitmq/cluster/server.rb +14 -18
- data/lib/rabbitmq/cluster/version.rb +1 -1
- data/spec/unit/etcd_spec.rb +20 -41
- data/spec/unit/server_spec.rb +34 -53
- metadata +3 -3
data/Rakefile
CHANGED
data/bin/rabbitmq-cluster
CHANGED
@@ -13,19 +13,16 @@ module RabbitMQ::Cluster
|
|
13
13
|
def aquire_lock
|
14
14
|
sleep 1 until lock = client.update('/rabbitmq/lock', true, false)
|
15
15
|
yield if lock
|
16
|
-
|
16
|
+
ensure
|
17
|
+
client.update('/rabbitmq/lock', false, true)
|
17
18
|
end
|
18
19
|
|
19
20
|
def nodes
|
20
|
-
(client.get('/rabbitmq/nodes') || {}).values
|
21
|
+
(client.get('/rabbitmq/nodes') || {}).values.sort
|
21
22
|
end
|
22
23
|
|
23
24
|
def register(node_name)
|
24
|
-
client.set(key_for(node_name), node_name
|
25
|
-
end
|
26
|
-
|
27
|
-
def deregister(node_name)
|
28
|
-
client.delete(key_for(node_name))
|
25
|
+
client.set(key_for(node_name), node_name, ttl: 10)
|
29
26
|
end
|
30
27
|
|
31
28
|
def erlang_cookie
|
@@ -26,12 +26,12 @@ module RabbitMQ::Cluster
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def synchronize
|
29
|
-
|
29
|
+
join_cluster if up?
|
30
|
+
return if etcd.nodes == running_nodes
|
30
31
|
|
31
32
|
etcd.aquire_lock do
|
32
|
-
stopped_nodes.each do |
|
33
|
-
|
34
|
-
etcd.deregister(node['name'])
|
33
|
+
stopped_nodes.each do |node_name|
|
34
|
+
system("rabbitmqctl forget_cluster_node #{node_name}")
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -41,31 +41,27 @@ module RabbitMQ::Cluster
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def up?
|
44
|
-
|
44
|
+
client.aliveness_test('/')['status'] == 'ok'
|
45
45
|
rescue Faraday::ConnectionFailed
|
46
46
|
false
|
47
47
|
end
|
48
48
|
|
49
49
|
private
|
50
50
|
|
51
|
+
def register
|
52
|
+
etcd.register(name)
|
53
|
+
end
|
54
|
+
|
51
55
|
def running_nodes
|
52
|
-
|
56
|
+
nodes(true)
|
53
57
|
end
|
54
58
|
|
55
59
|
def stopped_nodes
|
56
|
-
|
60
|
+
nodes(false)
|
57
61
|
end
|
58
62
|
|
59
|
-
def
|
60
|
-
|
61
|
-
client.vhost_create('aliveness-test')
|
62
|
-
end
|
63
|
-
|
64
|
-
unless client.user_permissions('guest').any? {|up| up['vhost'] == 'aliveness-test' }
|
65
|
-
client.user_set_permissions('guest', 'aliveness-test', '.*', '.*', '.*')
|
66
|
-
end
|
67
|
-
|
68
|
-
client.aliveness_test('aliveness-test')['status'] == 'ok'
|
63
|
+
def nodes(running)
|
64
|
+
client.nodes.select { |n| n["running"] == running }.map { |n| n["name"] }.sort
|
69
65
|
end
|
70
66
|
|
71
67
|
def join_cluster
|
@@ -74,7 +70,7 @@ module RabbitMQ::Cluster
|
|
74
70
|
system("rabbitmqctl join_cluster #{nodes_to_join.first}")
|
75
71
|
`rabbitmqctl start_app`
|
76
72
|
end
|
77
|
-
|
73
|
+
register if up?
|
78
74
|
end
|
79
75
|
|
80
76
|
def clustered?
|
data/spec/unit/etcd_spec.rb
CHANGED
@@ -24,44 +24,17 @@ describe RabbitMQ::Cluster::Etcd do
|
|
24
24
|
describe '#register' do
|
25
25
|
let(:nodename) { 'rabbit@mynode' }
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
expect(etcd_client).to receive(:set)
|
36
|
-
.with(
|
37
|
-
"/rabbitmq/nodes/#{nodename}",
|
38
|
-
nodename
|
39
|
-
)
|
40
|
-
subject.register(nodename)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context 'the node is allready registered' do
|
45
|
-
before do
|
46
|
-
allow(etcd_client).to receive(:exists?)
|
47
|
-
.with("/rabbitmq/nodes/#{nodename}")
|
48
|
-
.and_return true
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'does nothing' do
|
52
|
-
expect(etcd_client).to_not receive(:set)
|
53
|
-
subject.register(nodename)
|
54
|
-
end
|
27
|
+
it 'sets the key in etcd' do
|
28
|
+
expect(etcd_client).to receive(:set)
|
29
|
+
.with(
|
30
|
+
"/rabbitmq/nodes/#{nodename}",
|
31
|
+
nodename,
|
32
|
+
ttl: 10
|
33
|
+
)
|
34
|
+
subject.register(nodename)
|
55
35
|
end
|
56
36
|
end
|
57
37
|
|
58
|
-
describe '#deregister' do
|
59
|
-
it 'deletes the correct key' do
|
60
|
-
expect(etcd_client).to receive(:delete)
|
61
|
-
.with('/rabbitmq/nodes/rabbit@foobah')
|
62
|
-
subject.deregister('rabbit@foobah')
|
63
|
-
end
|
64
|
-
end
|
65
38
|
|
66
39
|
describe '#erlang_cookie' do
|
67
40
|
let(:erlang_cookie) { 'afbdgCVB23423bh324h' }
|
@@ -105,12 +78,6 @@ describe RabbitMQ::Cluster::Etcd do
|
|
105
78
|
|
106
79
|
subject.aquire_lock { thingy.run }
|
107
80
|
end
|
108
|
-
|
109
|
-
it 'gets angry if something odd happens' do
|
110
|
-
allow(etcd_client).to receive(:update).with('/rabbitmq/lock', false, true).and_return(false)
|
111
|
-
|
112
|
-
expect { subject.aquire_lock { thingy.run } }.to raise_error
|
113
|
-
end
|
114
81
|
end
|
115
82
|
|
116
83
|
describe "when we can't get the lock" do
|
@@ -124,5 +91,17 @@ describe RabbitMQ::Cluster::Etcd do
|
|
124
91
|
subject.aquire_lock { thingy.run }
|
125
92
|
end
|
126
93
|
end
|
94
|
+
|
95
|
+
describe 'when something explodes' do
|
96
|
+
before do
|
97
|
+
allow(etcd_client).to receive(:update).with('/rabbitmq/lock', false, true).and_return(true)
|
98
|
+
allow(etcd_client).to receive(:update).with('/rabbitmq/lock', true, false).and_return(true)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'gives the lock back' do
|
102
|
+
expect(etcd_client).to receive(:update).with('/rabbitmq/lock', false, true).and_return(true)
|
103
|
+
expect { subject.aquire_lock { fail } }.to raise_error
|
104
|
+
end
|
105
|
+
end
|
127
106
|
end
|
128
107
|
end
|
data/spec/unit/server_spec.rb
CHANGED
@@ -38,33 +38,6 @@ describe RabbitMQ::Cluster::Server do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
context 'we can can connect to the management api' do
|
41
|
-
context 'and the test vhost is allready setup' do
|
42
|
-
before do
|
43
|
-
allow(client).to receive(:vhosts).and_return([{'name' => 'aliveness-test'}])
|
44
|
-
allow(client).to receive(:user_permissions).and_return([{'vhost' => 'aliveness-test'}])
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'wont set up the vhost' do
|
48
|
-
expect(client).to_not receive(:vhost_create)
|
49
|
-
expect(client).to_not receive(:user_set_permissions)
|
50
|
-
subject.up?
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
context 'and the test vhost is not setup' do
|
55
|
-
|
56
|
-
before do
|
57
|
-
allow(client).to receive(:vhosts).and_return([])
|
58
|
-
allow(client).to receive(:user_permissions).and_return([])
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'will set up the vhost' do
|
62
|
-
expect(client).to receive(:vhost_create).with('aliveness-test')
|
63
|
-
expect(client).to receive(:user_set_permissions).with('guest', 'aliveness-test', '.*', '.*', '.*')
|
64
|
-
subject.up?
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
41
|
context 'the aliveness test is working' do
|
69
42
|
specify { expect(subject).to be_up }
|
70
43
|
end
|
@@ -97,7 +70,7 @@ describe RabbitMQ::Cluster::Server do
|
|
97
70
|
|
98
71
|
context 'waiting for the server to start' do
|
99
72
|
it 'waits until the server has started' do
|
100
|
-
expect(subject).to receive(:up?).
|
73
|
+
expect(subject).to receive(:up?).exactly(3).times.and_return(false, true)
|
101
74
|
subject.start
|
102
75
|
end
|
103
76
|
end
|
@@ -200,49 +173,57 @@ describe RabbitMQ::Cluster::Server do
|
|
200
173
|
describe '#synchronize' do
|
201
174
|
context 'etcd has more nodes than are running' do
|
202
175
|
before do
|
203
|
-
etcd.register('rabbit@node1')
|
204
|
-
etcd.register('rabbit@node2')
|
205
176
|
allow(client).to receive(:nodes)
|
206
177
|
.and_return([
|
207
178
|
{"name" => "rabbit@node1", "running" => true},
|
208
179
|
{"name" => "rabbit@node2", "running" => false}
|
209
180
|
])
|
210
|
-
allow(subject).to receive(:
|
211
|
-
allow(
|
181
|
+
allow(subject).to receive(:system)
|
182
|
+
allow(client).to receive(:aliveness_test).and_return("status" => "ok")
|
183
|
+
allow(client).to receive(:overview).and_return("cluster_name" => "rabbit@this_node")
|
212
184
|
end
|
213
185
|
|
214
|
-
|
215
|
-
|
216
|
-
|
186
|
+
context 'the node is up' do
|
187
|
+
it 'registers the node' do
|
188
|
+
expect(etcd).to receive(:register).with('rabbit@this_node')
|
189
|
+
subject.synchronize
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'the node is not up' do
|
194
|
+
before do
|
195
|
+
allow(client).to receive(:aliveness_test).and_return("status" => "agghghghgh")
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'does not register the node' do
|
199
|
+
expect(etcd).to_not receive(:register).with('rabbit@this_node')
|
200
|
+
subject.synchronize
|
201
|
+
end
|
217
202
|
end
|
218
203
|
|
219
204
|
it 'removes the stopped node from the cluster' do
|
220
|
-
expect(subject).to receive(:
|
205
|
+
expect(subject).to receive(:system)
|
221
206
|
.with('rabbitmqctl forget_cluster_node rabbit@node2')
|
222
207
|
subject.synchronize
|
223
208
|
end
|
224
209
|
|
225
|
-
it 'removes the stopped node from etcd' do
|
226
|
-
expect(etcd).to receive(:deregister)
|
227
|
-
.with('rabbit@node2')
|
228
|
-
subject.synchronize
|
229
|
-
end
|
230
|
-
end
|
231
210
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
211
|
+
context 'etcd nodes matches running nodes in the cluster' do
|
212
|
+
before do
|
213
|
+
etcd.register('rabbit@node1')
|
214
|
+
etcd.register('rabbit@node2')
|
215
|
+
allow(client).to receive(:nodes)
|
237
216
|
.and_return([
|
238
|
-
|
239
|
-
|
217
|
+
{"name" => "rabbit@node1", "running" => true},
|
218
|
+
{"name" => "rabbit@node2", "running" => true},
|
219
|
+
{"name" => "rabbit@this_node", "running" => true}
|
240
220
|
])
|
241
|
-
|
221
|
+
end
|
242
222
|
|
243
|
-
|
244
|
-
|
245
|
-
|
223
|
+
it 'will not remove any nodes' do
|
224
|
+
expect(subject).to_not receive(:system)
|
225
|
+
subject.synchronize
|
226
|
+
end
|
246
227
|
end
|
247
228
|
end
|
248
229
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rabbitmq-cluster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -144,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
144
144
|
version: '0'
|
145
145
|
segments:
|
146
146
|
- 0
|
147
|
-
hash: -
|
147
|
+
hash: -4607728886686367057
|
148
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
149
|
none: false
|
150
150
|
requirements:
|
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
153
|
version: '0'
|
154
154
|
segments:
|
155
155
|
- 0
|
156
|
-
hash: -
|
156
|
+
hash: -4607728886686367057
|
157
157
|
requirements: []
|
158
158
|
rubyforge_project:
|
159
159
|
rubygems_version: 1.8.25
|