zk-server 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +2 -0
- data/Rakefile +48 -0
- data/lib/zk-server.rb +30 -1
- data/lib/zk-server/config.rb +2 -2
- data/lib/zk-server/process.rb +23 -81
- data/lib/zk-server/server.rb +105 -0
- data/lib/zk-server/version.rb +1 -1
- data/spec/zk-server/process_spec.rb +4 -5
- metadata +5 -4
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -10,4 +10,52 @@ end
|
|
10
10
|
|
11
11
|
task :clean => 'yard:clean'
|
12
12
|
|
13
|
+
gemset_name = 'zk-server'
|
14
|
+
|
15
|
+
%w[1.8.7 1.9.2 jruby 1.9.3].each do |ns_name|
|
16
|
+
rvm_ruby = (ns_name == 'rbx') ? "rbx-2.0.testing" : ns_name
|
17
|
+
|
18
|
+
ruby_with_gemset = "#{rvm_ruby}@#{gemset_name}"
|
19
|
+
create_gemset_task_name = "mb:#{ns_name}:create_gemset"
|
20
|
+
bundle_task_name = "mb:#{ns_name}:bundle_install"
|
21
|
+
rspec_task_name = "mb:#{ns_name}:run_rspec"
|
22
|
+
|
23
|
+
phony_gemfile_link_name = "Gemfile.#{ns_name}"
|
24
|
+
phony_gemfile_lock_name = "#{phony_gemfile_link_name}.lock"
|
25
|
+
|
26
|
+
file phony_gemfile_link_name do
|
27
|
+
# apparently, rake doesn't deal with symlinks intelligently :P
|
28
|
+
ln_s('Gemfile', phony_gemfile_link_name) unless File.symlink?(phony_gemfile_link_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
task :clean do
|
32
|
+
rm_rf [phony_gemfile_lock_name, phony_gemfile_lock_name]
|
33
|
+
end
|
34
|
+
|
35
|
+
task create_gemset_task_name do
|
36
|
+
sh "rvm #{rvm_ruby} do rvm gemset create #{gemset_name}"
|
37
|
+
end
|
38
|
+
|
39
|
+
task bundle_task_name => [phony_gemfile_link_name, create_gemset_task_name] do
|
40
|
+
sh "rvm #{ruby_with_gemset} do bundle install --gemfile #{phony_gemfile_link_name}"
|
41
|
+
end
|
42
|
+
|
43
|
+
task rspec_task_name => bundle_task_name do
|
44
|
+
sh "rvm #{ruby_with_gemset} do env JRUBY_OPTS='--1.9' BUNDLE_GEMFILE=#{phony_gemfile_link_name} bundle exec rspec spec --fail-fast"
|
45
|
+
end
|
46
|
+
|
47
|
+
task "mb:#{ns_name}" => rspec_task_name
|
48
|
+
|
49
|
+
task "mb:test_all_rubies" => rspec_task_name
|
50
|
+
end
|
51
|
+
|
52
|
+
task 'mb:test_all' do
|
53
|
+
require 'benchmark'
|
54
|
+
tm = Benchmark.realtime do
|
55
|
+
Rake::Task['mb:test_all_rubies'].invoke
|
56
|
+
end
|
57
|
+
|
58
|
+
$stderr.puts "Test run took: #{tm}"
|
59
|
+
end
|
60
|
+
|
13
61
|
|
data/lib/zk-server.rb
CHANGED
@@ -19,12 +19,36 @@ module ZK
|
|
19
19
|
ZK_JAR_GEM = 'slyphon-zookeeper_jar'
|
20
20
|
LOG4J_GEM = 'slyphon-log4j'
|
21
21
|
|
22
|
+
def self.mri_187?
|
23
|
+
ruby_187? and not rubinius? and not jruby?
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.ruby_19?
|
27
|
+
false|(RUBY_VERSION =~ /\A1\.9/)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.ruby_187?
|
31
|
+
RUBY_VERSION == '1.8.7'
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.jruby?
|
35
|
+
defined?(::JRUBY_VERSION)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.jruby_19?
|
39
|
+
jruby? and ruby_19?
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.rubinius?
|
43
|
+
defined?(::Rubinius)
|
44
|
+
end
|
45
|
+
|
22
46
|
# Create a new {ZK::Server::Process} instance. if a block is given
|
23
47
|
# then yield the {Config} object to the block
|
24
48
|
#
|
25
49
|
# @yield [Config] server config instance if block given
|
26
50
|
def self.new(opts={})
|
27
|
-
Server::Process.new(opts).tap do |server|
|
51
|
+
ZK::Server::Process.new(opts).tap do |server|
|
28
52
|
yield server.config if block_given?
|
29
53
|
end
|
30
54
|
end
|
@@ -93,5 +117,10 @@ end
|
|
93
117
|
require 'zk-server/version'
|
94
118
|
require 'zk-server/logging'
|
95
119
|
require 'zk-server/config'
|
120
|
+
require 'zk-server/server'
|
96
121
|
require 'zk-server/process'
|
97
122
|
|
123
|
+
# if defined?(::JRUBY_VERSION)
|
124
|
+
# require 'zk-server/java_embedded'
|
125
|
+
# end
|
126
|
+
|
data/lib/zk-server/config.rb
CHANGED
@@ -118,12 +118,12 @@ module ZK
|
|
118
118
|
|
119
119
|
# @private
|
120
120
|
def classpath
|
121
|
-
@classpath ||= [Server.zk_jar_path, Server.log4j_jar_path, base_dir]
|
121
|
+
@classpath ||= [ZK::Server.zk_jar_path, ZK::Server.log4j_jar_path, base_dir]
|
122
122
|
end
|
123
123
|
|
124
124
|
# @private
|
125
125
|
def command_args
|
126
|
-
cmd = [Server.java_binary_path]
|
126
|
+
cmd = [ZK::Server.java_binary_path]
|
127
127
|
cmd += %W[-Dzookeeper.log.dir=#{log_dir} -Dzookeeper.root.logger=INFO,CONSOLE]
|
128
128
|
if enable_jmx
|
129
129
|
cmd += DEFAULT_JMX_ARGS
|
data/lib/zk-server/process.rb
CHANGED
@@ -7,42 +7,19 @@ module ZK
|
|
7
7
|
# By default, we will create a directory in the current working directory called 'zk-server'
|
8
8
|
# to store our data under (configurable).
|
9
9
|
#
|
10
|
-
class Process
|
11
|
-
extend Forwardable
|
12
|
-
include FileUtils
|
13
|
-
include Logging
|
14
|
-
|
15
|
-
def_delegators :config,
|
16
|
-
:base_dir, :data_dir, :log4j_props_path, :log_dir, :command_args,
|
17
|
-
:tick_time, :snap_count, :force_sync, :zoo_cfg_hash, :client_port,
|
18
|
-
:max_client_cnxns, :stdio_redirect_path, :zoo_cfg_path
|
19
|
-
|
20
|
-
# the {Config} object that will be used to configure this Process
|
21
|
-
attr_accessor :config
|
22
|
-
|
10
|
+
class Process < Server
|
23
11
|
attr_reader :exit_status
|
24
12
|
|
25
13
|
# how long should we wait for the child to start responding to 'ruok'?
|
26
14
|
attr_accessor :child_startup_timeout
|
27
15
|
|
28
16
|
def initialize(opts={})
|
29
|
-
@child_startup_timeout = opts.delete(:child_startup_timeout) || 6
|
30
|
-
@run_called = false
|
31
|
-
@config = Config.new(opts)
|
32
17
|
@exit_watching_thread = nil
|
33
18
|
|
34
19
|
@pid = nil
|
35
20
|
@exit_status = nil
|
36
21
|
|
37
|
-
|
38
|
-
@exit_cond = @mutex.new_cond
|
39
|
-
end
|
40
|
-
|
41
|
-
# removes all files related to this instance
|
42
|
-
# runs {#shutdown} first
|
43
|
-
def clobber!
|
44
|
-
shutdown
|
45
|
-
FileUtils.rm_rf(base_dir)
|
22
|
+
super
|
46
23
|
end
|
47
24
|
|
48
25
|
# true if the process was started and is still running
|
@@ -66,16 +43,15 @@ module ZK
|
|
66
43
|
%w[HUP TERM KILL].each do |signal|
|
67
44
|
logger.debug { "sending #{signal} to #{@pid}" }
|
68
45
|
|
46
|
+
return unless running? # jruby doesn't seem to get @exit_status ?
|
47
|
+
|
69
48
|
begin
|
70
49
|
::Process.kill(signal, @pid)
|
71
50
|
rescue Errno::ESRCH
|
72
|
-
|
51
|
+
return true
|
73
52
|
end
|
74
53
|
|
75
|
-
|
76
|
-
logger.debug { "process exited" }
|
77
|
-
break
|
78
|
-
end
|
54
|
+
@exit_cond.wait(5) # check running? on next pass
|
79
55
|
end
|
80
56
|
end
|
81
57
|
|
@@ -84,17 +60,6 @@ module ZK
|
|
84
60
|
true
|
85
61
|
end
|
86
62
|
|
87
|
-
# can we connect to the server, issue an 'ruok', and receive an 'imok'?
|
88
|
-
def ping?
|
89
|
-
TCPSocket.open('localhost', client_port) do |sock|
|
90
|
-
sock.puts('ruok')
|
91
|
-
sock.read == 'imok'
|
92
|
-
end
|
93
|
-
rescue
|
94
|
-
false
|
95
|
-
end
|
96
|
-
alias pingable? ping?
|
97
|
-
|
98
63
|
# the pid of our child process
|
99
64
|
def pid
|
100
65
|
@pid
|
@@ -111,7 +76,15 @@ module ZK
|
|
111
76
|
@run_called = true
|
112
77
|
|
113
78
|
create_files!
|
114
|
-
|
79
|
+
|
80
|
+
if ZK::Server.mri_187?
|
81
|
+
fork_and_exec!
|
82
|
+
elsif ZK::Server.jruby? and not ZK::Server.ruby_19?
|
83
|
+
raise "You must run Jruby in 1.9 compatibility mode! I'm very sorry, i need Kernel.spawn"
|
84
|
+
else
|
85
|
+
spawn!
|
86
|
+
end
|
87
|
+
|
115
88
|
spawn_exit_watching_thread
|
116
89
|
|
117
90
|
unless wait_until_ping(@child_startup_timeout)
|
@@ -124,14 +97,6 @@ module ZK
|
|
124
97
|
end
|
125
98
|
|
126
99
|
protected
|
127
|
-
def wait_until_ping(timeout=5)
|
128
|
-
times_up = timeout ? Time.now + timeout : 0
|
129
|
-
while Time.now < times_up
|
130
|
-
return true if ping?
|
131
|
-
end
|
132
|
-
false
|
133
|
-
end
|
134
|
-
|
135
100
|
def spawn_exit_watching_thread
|
136
101
|
@exit_watching_thread ||= Thread.new do
|
137
102
|
_, @exit_status = ::Process.wait2(@pid)
|
@@ -155,6 +120,14 @@ module ZK
|
|
155
120
|
nil
|
156
121
|
end
|
157
122
|
|
123
|
+
def spawn!
|
124
|
+
@pid ||= (
|
125
|
+
args = command_args()
|
126
|
+
args << { :err => [:child, :out], :out => [stdio_redirect_path, 'w'] }
|
127
|
+
::Kernel.spawn({}, *command_args)
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
158
131
|
def fork_and_exec!
|
159
132
|
@pid ||=
|
160
133
|
fork do # gah, use fork because 1.8.7 sucks
|
@@ -175,37 +148,6 @@ module ZK
|
|
175
148
|
end
|
176
149
|
end
|
177
150
|
|
178
|
-
def create_files!
|
179
|
-
mkdir_p base_dir
|
180
|
-
mkdir_p data_dir
|
181
|
-
write_zoo_cfg!
|
182
|
-
write_log4j_properties!
|
183
|
-
end
|
184
|
-
|
185
|
-
def write_log4j_properties!
|
186
|
-
unless File.exists?(log4j_props_path)
|
187
|
-
cp Server.default_log4j_props_path, log4j_props_path
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
def write_zoo_cfg!
|
192
|
-
File.open(zoo_cfg_path, 'w') do |fp|
|
193
|
-
fp.puts <<-EOS
|
194
|
-
tickTime=#{tick_time}
|
195
|
-
dataDir=#{data_dir}
|
196
|
-
clientPort=#{client_port}
|
197
|
-
maxClientCnxns=#{max_client_cnxns}
|
198
|
-
EOS
|
199
|
-
|
200
|
-
fp.puts("forceSync=#{force_sync}") if force_sync
|
201
|
-
fp.puts("snapCount=#{snap_count}") if snap_count
|
202
|
-
zoo_cfg_hash.each do |k,v|
|
203
|
-
fp.puts("#{k}=#{v}")
|
204
|
-
end
|
205
|
-
|
206
|
-
fp.fsync
|
207
|
-
end
|
208
|
-
end
|
209
151
|
end
|
210
152
|
end
|
211
153
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module ZK
|
2
|
+
module Server
|
3
|
+
# common base class for Process and JavaEmbedded classes
|
4
|
+
class Server
|
5
|
+
extend Forwardable
|
6
|
+
include FileUtils
|
7
|
+
include Logging
|
8
|
+
|
9
|
+
def_delegators :config,
|
10
|
+
:base_dir, :data_dir, :log4j_props_path, :log_dir, :command_args,
|
11
|
+
:tick_time, :snap_count, :force_sync, :zoo_cfg_hash, :client_port,
|
12
|
+
:max_client_cnxns, :stdio_redirect_path, :zoo_cfg_path
|
13
|
+
|
14
|
+
# the {Config} object that will be used to configure this Process
|
15
|
+
attr_accessor :config
|
16
|
+
|
17
|
+
def initialize(opts={})
|
18
|
+
@child_startup_timeout = opts.delete(:child_startup_timeout) || 6
|
19
|
+
|
20
|
+
@run_called = false
|
21
|
+
@config = Config.new(opts)
|
22
|
+
|
23
|
+
@mutex = Monitor.new
|
24
|
+
@exit_cond = @mutex.new_cond
|
25
|
+
end
|
26
|
+
|
27
|
+
# removes all files related to this instance
|
28
|
+
# runs {#shutdown} first
|
29
|
+
def clobber!
|
30
|
+
shutdown
|
31
|
+
FileUtils.rm_rf(base_dir)
|
32
|
+
end
|
33
|
+
|
34
|
+
# is the server running?
|
35
|
+
def running?
|
36
|
+
raise NotImplementedError
|
37
|
+
end
|
38
|
+
|
39
|
+
# shut down the server, gracefully if possible, with force if necessary
|
40
|
+
def shutdown
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
# can we connect to the server, issue an 'ruok', and receive an 'imok'?
|
45
|
+
def ping?
|
46
|
+
TCPSocket.open('localhost', client_port) do |sock|
|
47
|
+
sock.puts('ruok')
|
48
|
+
sock.read == 'imok'
|
49
|
+
end
|
50
|
+
rescue
|
51
|
+
false
|
52
|
+
end
|
53
|
+
alias pingable? ping?
|
54
|
+
|
55
|
+
# start the server
|
56
|
+
def run
|
57
|
+
raise NotImplementedError
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
def wait_until_ping(timeout=5)
|
62
|
+
times_up = timeout ? Time.now + timeout : 0
|
63
|
+
while Time.now < times_up
|
64
|
+
return true if ping?
|
65
|
+
end
|
66
|
+
false
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_files!
|
70
|
+
mkdir_p base_dir
|
71
|
+
mkdir_p data_dir
|
72
|
+
write_zoo_cfg!
|
73
|
+
write_log4j_properties!
|
74
|
+
mkdir_p(File.dirname(stdio_redirect_path))
|
75
|
+
end
|
76
|
+
|
77
|
+
def write_log4j_properties!
|
78
|
+
unless File.exists?(log4j_props_path)
|
79
|
+
cp ZK::Server.default_log4j_props_path, log4j_props_path
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def write_zoo_cfg!
|
84
|
+
File.open(zoo_cfg_path, 'w') do |fp|
|
85
|
+
fp.puts <<-EOS
|
86
|
+
tickTime=#{tick_time}
|
87
|
+
dataDir=#{data_dir}
|
88
|
+
clientPort=#{client_port}
|
89
|
+
maxClientCnxns=#{max_client_cnxns}
|
90
|
+
EOS
|
91
|
+
|
92
|
+
fp.puts("forceSync=#{force_sync}") if force_sync
|
93
|
+
fp.puts("snapCount=#{snap_count}") if snap_count
|
94
|
+
zoo_cfg_hash.each do |k,v|
|
95
|
+
fp.puts("#{k}=#{v}")
|
96
|
+
end
|
97
|
+
|
98
|
+
fp.fsync
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
data/lib/zk-server/version.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'tempfile'
|
3
2
|
|
4
3
|
describe ZK::Server::Process do
|
5
|
-
let(:tmpdir) {
|
6
|
-
'/tmp/zookeeper'
|
7
|
-
}
|
4
|
+
let(:tmpdir) { '/tmp/zookeeper' }
|
8
5
|
|
9
6
|
subject do
|
10
|
-
|
7
|
+
described_class.new(:client_port => 21812, :base_dir => tmpdir)
|
11
8
|
end
|
12
9
|
|
13
10
|
after do
|
@@ -17,6 +14,8 @@ describe ZK::Server::Process do
|
|
17
14
|
end
|
18
15
|
|
19
16
|
it %[should spawn a ZK server, ping, and then shutdown properly] do
|
17
|
+
# pending "cannot run this under JRuby" if defined?(::JRUBY_VERSION)
|
18
|
+
|
20
19
|
subject.run
|
21
20
|
subject.should be_pingable
|
22
21
|
subject.should be_running
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zk-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 59
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 9
|
9
|
+
- 0
|
10
|
+
version: 0.9.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jonathan D. Simms
|
@@ -88,6 +88,7 @@ files:
|
|
88
88
|
- lib/zk-server/log4j.properties
|
89
89
|
- lib/zk-server/logging.rb
|
90
90
|
- lib/zk-server/process.rb
|
91
|
+
- lib/zk-server/server.rb
|
91
92
|
- lib/zk-server/version.rb
|
92
93
|
- spec/spec_helper.rb
|
93
94
|
- spec/zk-server/process_spec.rb
|