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 CHANGED
@@ -17,3 +17,5 @@ test/version_tmp
17
17
  tmp
18
18
  .rvmrc
19
19
  zookeeper/
20
+ .ctags_paths
21
+ Gemfile.*
data/Gemfile CHANGED
@@ -2,6 +2,8 @@ source :rubygems
2
2
 
3
3
  # gem 'zk', :path => '~/zk'
4
4
 
5
+ gem 'rake', '>= 0.9'
6
+
5
7
  group :development do
6
8
  gem 'pry'
7
9
  end
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
 
@@ -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
+
@@ -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
@@ -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
- @mutex = Monitor.new
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
- break
51
+ return true
73
52
  end
74
53
 
75
- if @exit_status or @exit_cond.wait(5)
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
- fork_and_exec!
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
+
@@ -1,5 +1,5 @@
1
1
  module ZK
2
2
  module Server
3
- VERSION = "0.8.1"
3
+ VERSION = "0.9.0" unless defined?(::ZK::Server::VERSION)
4
4
  end
5
5
  end
@@ -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
- ZK::Server::Process.new(:client_port => 21812, :base_dir => tmpdir)
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: 61
4
+ hash: 59
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 8
9
- - 1
10
- version: 0.8.1
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