zookeeper 0.9.3 → 0.9.4
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/CHANGELOG +7 -0
- data/Gemfile +2 -1
- data/Rakefile +35 -10
- data/ext/zookeeper_base.rb +36 -15
- data/lib/zookeeper/version.rb +1 -1
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
v0.9.4 Fix shutdown timing bug
|
2
|
+
|
3
|
+
* Because we now release the GIL, ruby may call close while there's still
|
4
|
+
a pending synchronous call (since we give up the interpreter during that
|
5
|
+
time). Protect calls with a mutex so that close can only be called when
|
6
|
+
there isn't an in-flight call.
|
7
|
+
|
1
8
|
v0.9.3 Event thread shutdown fix, Windows compatibility fix
|
2
9
|
|
3
10
|
* Use a 'shutdown thread' to coordinate cleanup if close is called from the
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -2,17 +2,24 @@
|
|
2
2
|
# ENV.fetch('GEM_HOME').split('@').last
|
3
3
|
# end
|
4
4
|
|
5
|
-
GEM_FILES = FileList['
|
5
|
+
GEM_FILES = FileList['*zookeeper-*.gem']
|
6
|
+
|
7
|
+
# need to releaase under both names until ZK is updated to use just 'zookeeper'
|
8
|
+
GEM_NAMES = %w[zookeeper slyphon-zookeeper]
|
6
9
|
|
7
10
|
namespace :mb do
|
8
11
|
namespace :gems do
|
9
12
|
task :build do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
+
GEM_NAMES.each do |gem_name|
|
14
|
+
ENV['JAVA_GEM'] = nil
|
15
|
+
sh "rvm 1.8.7 do env ZOOKEEPER_GEM_NAME='#{gem_name}' gem build zookeeper.gemspec"
|
16
|
+
sh "rvm 1.8.7 do env JAVA_GEM=1 ZOOKEEPER_GEM_NAME='#{gem_name}' gem build zookeeper.gemspec"
|
17
|
+
end
|
13
18
|
end
|
14
19
|
|
15
|
-
task :push do
|
20
|
+
task :push => :build do
|
21
|
+
raise "No gemfiles to push!" if GEM_FILES.empty?
|
22
|
+
|
16
23
|
GEM_FILES.each do |gem|
|
17
24
|
sh "gem push #{gem}"
|
18
25
|
end
|
@@ -61,7 +68,7 @@ gemset_name = 'zookeeper'
|
|
61
68
|
task clobber_task_name do
|
62
69
|
unless rvm_ruby == 'jruby'
|
63
70
|
cd 'ext' do
|
64
|
-
sh "rake clobber"
|
71
|
+
sh "rvm #{ruby_with_gemset} do bundle exec rake clobber"
|
65
72
|
end
|
66
73
|
end
|
67
74
|
end
|
@@ -69,7 +76,7 @@ gemset_name = 'zookeeper'
|
|
69
76
|
task clean_task_name do
|
70
77
|
unless rvm_ruby == 'jruby'
|
71
78
|
cd 'ext' do
|
72
|
-
sh "rake clean"
|
79
|
+
sh "rvm #{ruby_with_gemset} do bundle exec rake clean"
|
73
80
|
end
|
74
81
|
end
|
75
82
|
end
|
@@ -77,7 +84,7 @@ gemset_name = 'zookeeper'
|
|
77
84
|
task build_task_name => [create_gemset_name, clean_task_name] do
|
78
85
|
unless rvm_ruby == 'jruby'
|
79
86
|
cd 'ext' do
|
80
|
-
sh "rvm #{ruby_with_gemset} do rake build"
|
87
|
+
sh "rvm #{ruby_with_gemset} do bundle exec rake build"
|
81
88
|
end
|
82
89
|
end
|
83
90
|
end
|
@@ -104,8 +111,6 @@ task "mb:test_all" do
|
|
104
111
|
$stderr.puts "Test run took: #{t} s"
|
105
112
|
end
|
106
113
|
|
107
|
-
task :default => 'mb:1.9.3'
|
108
|
-
|
109
114
|
task :clobber do
|
110
115
|
rm_rf 'tmp'
|
111
116
|
end
|
@@ -137,3 +142,23 @@ task :build do
|
|
137
142
|
end
|
138
143
|
end
|
139
144
|
|
145
|
+
namespace :spec do
|
146
|
+
task :define do
|
147
|
+
require 'rubygems'
|
148
|
+
require 'bundler/setup'
|
149
|
+
require 'rspec/core/rake_task'
|
150
|
+
|
151
|
+
RSpec::Core::RakeTask.new('spec:runner') do |t|
|
152
|
+
t.rspec_opts = '-f d' if ENV['TRAVIS']
|
153
|
+
end
|
154
|
+
|
155
|
+
task 'spec:runner' => :build
|
156
|
+
end
|
157
|
+
|
158
|
+
task :run => :define do
|
159
|
+
Rake::Task['spec:runner'].invoke
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
task :default => 'spec:run'
|
164
|
+
|
data/ext/zookeeper_base.rb
CHANGED
@@ -26,8 +26,29 @@ class ZookeeperBase
|
|
26
26
|
ZOO_LOG_LEVEL_INFO = 3
|
27
27
|
ZOO_LOG_LEVEL_DEBUG = 4
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
|
30
|
+
# this is unfortunately necessary to prevent a really horrendous race in
|
31
|
+
# shutdown, where some other thread calls close in the middle of a
|
32
|
+
# synchronous operation (thanks to the GIL-releasing wrappers, we now
|
33
|
+
# have this problem). so we need to make sure only one thread can be calling
|
34
|
+
# a synchronous operation at a time.
|
35
|
+
#
|
36
|
+
# this might be solved by waiting for a condition where there are no "in flight"
|
37
|
+
# operations (thereby allowing multiple threads to make requests simultaneously),
|
38
|
+
# but this would represent quite a bit of added complexity, and questionable
|
39
|
+
# performance gains.
|
40
|
+
#
|
41
|
+
def self.synchronized_delegation(provider, *syms)
|
42
|
+
syms.each do |sym|
|
43
|
+
class_eval(<<-EOM, __FILE__, __LINE__+1)
|
44
|
+
def #{sym}(*a, &b)
|
45
|
+
@mutex.synchronize { #{provider}.#{sym}(*a, &b) }
|
46
|
+
end
|
47
|
+
EOM
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
synchronized_delegation :@czk, :get_children, :exists, :delete, :get, :set, :set_acl, :get_acl, :client_id, :sync
|
31
52
|
|
32
53
|
# some state methods need to be more paranoid about locking to ensure the correct
|
33
54
|
# state is returned
|
@@ -90,17 +111,13 @@ class ZookeeperBase
|
|
90
111
|
|
91
112
|
reopen(timeout)
|
92
113
|
end
|
93
|
-
|
94
|
-
# synchronized accessor to the @czk instance
|
95
|
-
# @private
|
96
|
-
def czk
|
97
|
-
@mutex.synchronize { @czk }
|
98
|
-
end
|
99
|
-
|
114
|
+
|
100
115
|
# if either of these happen, the user will need to renegotiate a connection via reopen
|
101
116
|
def assert_open
|
102
|
-
|
103
|
-
|
117
|
+
@mutex.synchronize do
|
118
|
+
raise ZookeeperException::SessionExpired if state == ZOO_EXPIRED_SESSION_STATE
|
119
|
+
raise ZookeeperException::NotConnected unless connected?
|
120
|
+
end
|
104
121
|
end
|
105
122
|
|
106
123
|
def close
|
@@ -118,7 +135,7 @@ class ZookeeperBase
|
|
118
135
|
# is pretty damn annoying. this is used to clean things up.
|
119
136
|
def create(*args)
|
120
137
|
# since we don't care about the inputs, just glob args
|
121
|
-
rc, new_path = czk.create(*args)
|
138
|
+
rc, new_path = @mutex.synchronize { @czk.create(*args) }
|
122
139
|
[rc, strip_chroot_from(new_path)]
|
123
140
|
end
|
124
141
|
|
@@ -139,15 +156,19 @@ class ZookeeperBase
|
|
139
156
|
|
140
157
|
def state
|
141
158
|
return ZOO_CLOSED_STATE if closed?
|
142
|
-
czk.state
|
159
|
+
@mutex.synchronize { @czk.state }
|
143
160
|
end
|
144
161
|
|
145
162
|
def session_id
|
146
|
-
|
163
|
+
@mutex.synchronize do
|
164
|
+
cid = client_id and cid.session_id
|
165
|
+
end
|
147
166
|
end
|
148
167
|
|
149
168
|
def session_passwd
|
150
|
-
|
169
|
+
@mutex.synchronize do
|
170
|
+
cid = client_id and cid.passwd
|
171
|
+
end
|
151
172
|
end
|
152
173
|
|
153
174
|
# we are closed if there is no @czk instance or @czk.closed?
|
data/lib/zookeeper/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zookeeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 51
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 4
|
10
|
+
version: 0.9.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Phillip Pearson
|
@@ -20,7 +20,7 @@ autorequire:
|
|
20
20
|
bindir: bin
|
21
21
|
cert_chain: []
|
22
22
|
|
23
|
-
date: 2012-05-
|
23
|
+
date: 2012-05-07 00:00:00 Z
|
24
24
|
dependencies: []
|
25
25
|
|
26
26
|
description: |+
|