rabbitmq-cluster 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|