zeevex_cluster 0.2.1
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/.gitignore +5 -0
- data/Gemfile +22 -0
- data/Rakefile +44 -0
- data/doc/BUGS-zookeeper.txt +60 -0
- data/doc/TODO.txt +85 -0
- data/lib/zeevex_cluster/base.rb +95 -0
- data/lib/zeevex_cluster/coordinator/base_key_val_store.rb +85 -0
- data/lib/zeevex_cluster/coordinator/memcached.rb +118 -0
- data/lib/zeevex_cluster/coordinator/mysql.rb +396 -0
- data/lib/zeevex_cluster/coordinator/redis.rb +101 -0
- data/lib/zeevex_cluster/coordinator.rb +29 -0
- data/lib/zeevex_cluster/election.rb +102 -0
- data/lib/zeevex_cluster/message.rb +52 -0
- data/lib/zeevex_cluster/nil_logger.rb +7 -0
- data/lib/zeevex_cluster/serializer/json_hash.rb +67 -0
- data/lib/zeevex_cluster/serializer.rb +27 -0
- data/lib/zeevex_cluster/static.rb +67 -0
- data/lib/zeevex_cluster/strategy/base.rb +92 -0
- data/lib/zeevex_cluster/strategy/cas.rb +403 -0
- data/lib/zeevex_cluster/strategy/static.rb +55 -0
- data/lib/zeevex_cluster/strategy/unclustered.rb +9 -0
- data/lib/zeevex_cluster/strategy/zookeeper.rb +163 -0
- data/lib/zeevex_cluster/strategy.rb +12 -0
- data/lib/zeevex_cluster/synchronized.rb +46 -0
- data/lib/zeevex_cluster/unclustered.rb +11 -0
- data/lib/zeevex_cluster/util/logging.rb +7 -0
- data/lib/zeevex_cluster/util.rb +15 -0
- data/lib/zeevex_cluster/version.rb +3 -0
- data/lib/zeevex_cluster.rb +29 -0
- data/script/election.rb +46 -0
- data/script/memc.rb +13 -0
- data/script/mysql.rb +25 -0
- data/script/redis.rb +14 -0
- data/script/repl +10 -0
- data/script/repl.rb +8 -0
- data/script/ser.rb +11 -0
- data/script/static.rb +34 -0
- data/script/testall +2 -0
- data/spec/cluster_static_spec.rb +49 -0
- data/spec/cluster_unclustered_spec.rb +32 -0
- data/spec/coordinator/coordinator_memcached_spec.rb +102 -0
- data/spec/message_spec.rb +38 -0
- data/spec/serializer/json_hash_spec.rb +68 -0
- data/spec/shared_master_examples.rb +20 -0
- data/spec/shared_member_examples.rb +39 -0
- data/spec/shared_non_master_examples.rb +8 -0
- data/spec/spec_helper.rb +14 -0
- data/zeevex_cluster.gemspec +43 -0
- metadata +298 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
require 'zeevex_cluster/message.rb'
|
3
|
+
|
4
|
+
#
|
5
|
+
# REQUIRED_KEYS = %w{source sequence sent_at expires_at contents content_type encoding}
|
6
|
+
#
|
7
|
+
|
8
|
+
describe ZeevexCluster::Message do
|
9
|
+
subject { ZeevexCluster::Message.new :contents => '{foo: 1}', :source => 'node1' }
|
10
|
+
|
11
|
+
context 'creation' do
|
12
|
+
it { should be_a(Hash) }
|
13
|
+
it { should have_key(:contents) }
|
14
|
+
it { should have_key(:source) }
|
15
|
+
it { should_not be_valid }
|
16
|
+
|
17
|
+
context 'default values' do
|
18
|
+
it { should have_key(:content_type) }
|
19
|
+
its(:content_type) { should == 'application/json' }
|
20
|
+
its(:encoding) { should be_nil }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'method-style access' do
|
25
|
+
it { should respond_to("contents") }
|
26
|
+
its(:source) { should == 'node1' }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'validation' do
|
30
|
+
it 'should not be valid without required keys' do
|
31
|
+
subject.should_not be_valid
|
32
|
+
end
|
33
|
+
it 'should be valid if required keys are added' do
|
34
|
+
subject.merge(:sequence => 1, :sent_at => Time.now, :expires_at => Time.now + 7200).should be_valid
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../spec_helper')
|
2
|
+
require 'zeevex_cluster/serializer/json_hash.rb'
|
3
|
+
|
4
|
+
describe ZeevexCluster::Serializer::JsonHash do
|
5
|
+
let :serializer do
|
6
|
+
ZeevexCluster::Serializer::JsonHash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'cas host tokens' do
|
10
|
+
let :now do
|
11
|
+
Time.at(1355418862)
|
12
|
+
end
|
13
|
+
let :times do
|
14
|
+
{:joined_at => now - 7200, :timestamp => now, :locked_at => now - 600}
|
15
|
+
end
|
16
|
+
|
17
|
+
let :nodehash do
|
18
|
+
times.merge({:nodename => 'mynode'})
|
19
|
+
end
|
20
|
+
|
21
|
+
let :json do
|
22
|
+
serializer.serialize(nodehash)
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'serialized form' do
|
26
|
+
subject { json }
|
27
|
+
it { should be_a(String) }
|
28
|
+
it { should match /"joined_at":\{[^}]*1355411662/ }
|
29
|
+
it { should match /"locked_at":\{[^}]*1355418262/ }
|
30
|
+
it { should match /"timestamp":\{[^}]*1355418862/ }
|
31
|
+
it { should match /"nodename":\s*"mynode"/ }
|
32
|
+
it { should match /^\{.*\}$/ }
|
33
|
+
it 'should be a valid JSON string' do
|
34
|
+
JSON.parse(subject).should be_a(Hash)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'deserialized hash' do
|
39
|
+
subject { serializer.deserialize(json) }
|
40
|
+
it { should have(4).keys }
|
41
|
+
it { should == nodehash }
|
42
|
+
it 'should have only symbol keys' do
|
43
|
+
subject.keys.reject {|k| k.is_a?(Symbol) }.should be_empty
|
44
|
+
end
|
45
|
+
it 'should have 3 time fields' do
|
46
|
+
subject.values.select {|key| key.is_a?(Time) }.should have(3).items
|
47
|
+
end
|
48
|
+
it 'should have matching times for 3 fields' do
|
49
|
+
times.map {|(key, val)| subject[key].utc.should == val.utc }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'nested hashes' do
|
54
|
+
let :innerhash do
|
55
|
+
{:when => now - 7200, :members => ["a", "b"]}
|
56
|
+
end
|
57
|
+
|
58
|
+
let :tophash do
|
59
|
+
{:mlist => innerhash, :timestamp => now}
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should roundtrip' do
|
63
|
+
serializer.deserialize( serializer.serialize(tophash) ).should == tophash
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
shared_examples_for 'master_node' do
|
2
|
+
it { should be_master }
|
3
|
+
it 'should have the same nodename as the master' do
|
4
|
+
subject.master.should == subject.nodename
|
5
|
+
end
|
6
|
+
it 'should execute run_if_master block' do
|
7
|
+
subject.run_if_master do
|
8
|
+
:ran
|
9
|
+
end.should == :ran
|
10
|
+
end
|
11
|
+
it 'should no longer be master after leaving' do
|
12
|
+
expect { subject.leave }.
|
13
|
+
to change { subject.master? }.
|
14
|
+
from(true).to(false)
|
15
|
+
end
|
16
|
+
#it 'should resign before leaving the cluster' do
|
17
|
+
# subject.should_receive(:resign!).and_return(true)
|
18
|
+
# subject.leave
|
19
|
+
#end
|
20
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# depends on a couple of let bindings
|
3
|
+
#
|
4
|
+
# - autojoined: newly created, autojoined
|
5
|
+
# - non_autojoined: newly created, autojoin => false
|
6
|
+
#
|
7
|
+
# and a method:
|
8
|
+
#
|
9
|
+
# - new_cluster(options)
|
10
|
+
#
|
11
|
+
shared_examples_for 'member_node' do
|
12
|
+
context 'when auto-joined' do
|
13
|
+
subject { new_cluster(:autojoin => true) }
|
14
|
+
|
15
|
+
it { should be_member }
|
16
|
+
|
17
|
+
it 'should have a nodename' do
|
18
|
+
subject.nodename.should_not be_nil
|
19
|
+
subject.nodename.should_not be_empty
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should become non-member after leaving' do
|
23
|
+
expect { subject.leave }.
|
24
|
+
to change { subject.member? }.from(true).to(false)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when not auto-joined' do
|
29
|
+
subject { new_cluster(:autojoin => false) }
|
30
|
+
|
31
|
+
it { should_not be_member }
|
32
|
+
|
33
|
+
it 'should become member after joining' do
|
34
|
+
expect { subject.join }.
|
35
|
+
to change { subject.member? }.from(false).to(true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
require 'zeevex_cluster'
|
5
|
+
require 'zeevex_cluster/static'
|
6
|
+
require 'zeevex_cluster/unclustered'
|
7
|
+
require 'zeevex_cluster/unclustered'
|
8
|
+
|
9
|
+
require 'pry'
|
10
|
+
require 'timeout'
|
11
|
+
|
12
|
+
require File.expand_path(File.dirname(__FILE__) + '/shared_master_examples.rb')
|
13
|
+
require File.expand_path(File.dirname(__FILE__) + '/shared_non_master_examples.rb')
|
14
|
+
require File.expand_path(File.dirname(__FILE__) + '/shared_member_examples.rb')
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "zeevex_cluster/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "zeevex_cluster"
|
7
|
+
s.version = ZeevexCluster::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Robert Sanders"]
|
10
|
+
s.email = ["robert@zeevex.com"]
|
11
|
+
s.homepage = "http://github.com/zeevex/zeevex_cluster"
|
12
|
+
s.summary = %q{Use a shared coordinator service to reliably elect a master in a cluster of processes.}
|
13
|
+
s.description = %q{Using a shared data storage service like MySQL, Memcache, Redis, or ZooKeeper, one process of many can be elected a cluster master. Notification of cluster membership changes is also provided.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "zeevex_cluster"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency 'state_machine'
|
23
|
+
s.add_dependency 'json'
|
24
|
+
s.add_dependency 'zeevex_proxy'
|
25
|
+
s.add_dependency 'zeevex_threadsafe'
|
26
|
+
s.add_dependency 'countdownlatch', '~> 1.0.0'
|
27
|
+
s.add_dependency 'atomic', '~> 1.0.0'
|
28
|
+
|
29
|
+
s.add_dependency 'hookem', '~> 0.0.1'
|
30
|
+
|
31
|
+
## other headius utils
|
32
|
+
# s.add_dependency 'thread_safe'
|
33
|
+
|
34
|
+
s.add_development_dependency 'rspec', '~> 2.9.0'
|
35
|
+
s.add_development_dependency 'rake'
|
36
|
+
s.add_development_dependency 'pry'
|
37
|
+
|
38
|
+
s.add_development_dependency 'memcache-client', '> 1.7.0'
|
39
|
+
s.add_development_dependency 'redis'
|
40
|
+
|
41
|
+
# s.add_development_dependency 'zk'
|
42
|
+
# s.add_development_dependency 'zk-group'
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,298 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zeevex_cluster
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Robert Sanders
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-08-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: state_machine
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: zeevex_proxy
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: zeevex_threadsafe
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: countdownlatch
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.0.0
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.0.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: atomic
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.0.0
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.0.0
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: hookem
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.0.1
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 0.0.1
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rspec
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ~>
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: 2.9.0
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 2.9.0
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rake
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: pry
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: memcache-client
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>'
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: 1.7.0
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>'
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: 1.7.0
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: redis
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
description: Using a shared data storage service like MySQL, Memcache, Redis, or ZooKeeper,
|
207
|
+
one process of many can be elected a cluster master. Notification of cluster membership
|
208
|
+
changes is also provided.
|
209
|
+
email:
|
210
|
+
- robert@zeevex.com
|
211
|
+
executables: []
|
212
|
+
extensions: []
|
213
|
+
extra_rdoc_files: []
|
214
|
+
files:
|
215
|
+
- .gitignore
|
216
|
+
- Gemfile
|
217
|
+
- Rakefile
|
218
|
+
- doc/BUGS-zookeeper.txt
|
219
|
+
- doc/TODO.txt
|
220
|
+
- lib/zeevex_cluster.rb
|
221
|
+
- lib/zeevex_cluster/base.rb
|
222
|
+
- lib/zeevex_cluster/coordinator.rb
|
223
|
+
- lib/zeevex_cluster/coordinator/base_key_val_store.rb
|
224
|
+
- lib/zeevex_cluster/coordinator/memcached.rb
|
225
|
+
- lib/zeevex_cluster/coordinator/mysql.rb
|
226
|
+
- lib/zeevex_cluster/coordinator/redis.rb
|
227
|
+
- lib/zeevex_cluster/election.rb
|
228
|
+
- lib/zeevex_cluster/message.rb
|
229
|
+
- lib/zeevex_cluster/nil_logger.rb
|
230
|
+
- lib/zeevex_cluster/serializer.rb
|
231
|
+
- lib/zeevex_cluster/serializer/json_hash.rb
|
232
|
+
- lib/zeevex_cluster/static.rb
|
233
|
+
- lib/zeevex_cluster/strategy.rb
|
234
|
+
- lib/zeevex_cluster/strategy/base.rb
|
235
|
+
- lib/zeevex_cluster/strategy/cas.rb
|
236
|
+
- lib/zeevex_cluster/strategy/static.rb
|
237
|
+
- lib/zeevex_cluster/strategy/unclustered.rb
|
238
|
+
- lib/zeevex_cluster/strategy/zookeeper.rb
|
239
|
+
- lib/zeevex_cluster/synchronized.rb
|
240
|
+
- lib/zeevex_cluster/unclustered.rb
|
241
|
+
- lib/zeevex_cluster/util.rb
|
242
|
+
- lib/zeevex_cluster/util/logging.rb
|
243
|
+
- lib/zeevex_cluster/version.rb
|
244
|
+
- script/election.rb
|
245
|
+
- script/memc.rb
|
246
|
+
- script/mysql.rb
|
247
|
+
- script/redis.rb
|
248
|
+
- script/repl
|
249
|
+
- script/repl.rb
|
250
|
+
- script/ser.rb
|
251
|
+
- script/static.rb
|
252
|
+
- script/testall
|
253
|
+
- spec/cluster_static_spec.rb
|
254
|
+
- spec/cluster_unclustered_spec.rb
|
255
|
+
- spec/coordinator/coordinator_memcached_spec.rb
|
256
|
+
- spec/message_spec.rb
|
257
|
+
- spec/serializer/json_hash_spec.rb
|
258
|
+
- spec/shared_master_examples.rb
|
259
|
+
- spec/shared_member_examples.rb
|
260
|
+
- spec/shared_non_master_examples.rb
|
261
|
+
- spec/spec_helper.rb
|
262
|
+
- zeevex_cluster.gemspec
|
263
|
+
homepage: http://github.com/zeevex/zeevex_cluster
|
264
|
+
licenses: []
|
265
|
+
post_install_message:
|
266
|
+
rdoc_options: []
|
267
|
+
require_paths:
|
268
|
+
- lib
|
269
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
270
|
+
none: false
|
271
|
+
requirements:
|
272
|
+
- - ! '>='
|
273
|
+
- !ruby/object:Gem::Version
|
274
|
+
version: '0'
|
275
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
276
|
+
none: false
|
277
|
+
requirements:
|
278
|
+
- - ! '>='
|
279
|
+
- !ruby/object:Gem::Version
|
280
|
+
version: '0'
|
281
|
+
requirements: []
|
282
|
+
rubyforge_project: zeevex_cluster
|
283
|
+
rubygems_version: 1.8.23
|
284
|
+
signing_key:
|
285
|
+
specification_version: 3
|
286
|
+
summary: Use a shared coordinator service to reliably elect a master in a cluster
|
287
|
+
of processes.
|
288
|
+
test_files:
|
289
|
+
- spec/cluster_static_spec.rb
|
290
|
+
- spec/cluster_unclustered_spec.rb
|
291
|
+
- spec/coordinator/coordinator_memcached_spec.rb
|
292
|
+
- spec/message_spec.rb
|
293
|
+
- spec/serializer/json_hash_spec.rb
|
294
|
+
- spec/shared_master_examples.rb
|
295
|
+
- spec/shared_member_examples.rb
|
296
|
+
- spec/shared_non_master_examples.rb
|
297
|
+
- spec/spec_helper.rb
|
298
|
+
has_rdoc:
|