zookeeper 1.0.3-java → 1.0.4-java

Sign up to get free protection for your applications and to get access to all the features.
data/ext/c_zookeeper.rb CHANGED
@@ -53,6 +53,13 @@ class CZookeeper
53
53
 
54
54
  @_session_timeout_msec = DEFAULT_SESSION_TIMEOUT_MSEC
55
55
 
56
+ if cid = opts[:client_id]
57
+ raise ArgumentError, "opts[:client_id] must be a CZookeeper::ClientId" unless cid.kind_of?(ClientId)
58
+ raise ArgumentError, "session_id must not be nil" if cid.session_id.nil?
59
+ end
60
+
61
+ @_client_id = opts[:client_id]
62
+
56
63
  @start_stop_mutex = Monitor.new
57
64
 
58
65
  # used to signal that we're running
data/ext/dbg.h CHANGED
@@ -45,7 +45,7 @@
45
45
  // like check_debug_goto, but the label is implicitly 'error'
46
46
  #define check_debug(A, M, ...) check_debug_goto(A, error, M, ##__VA_ARGS__)
47
47
 
48
- #define zkrb_debug(M, ...) if (ZKRBDebugging) fprintf(stderr, "DEBUG %p:%s:%d: " M "\n", pthread_self(), __FILE__, __LINE__, ##__VA_ARGS__)
48
+ #define zkrb_debug(M, ...) if (ZKRBDebugging) fprintf(stderr, "DEBUG %p:%s:%d: " M "\n", (void *)pthread_self(), __FILE__, __LINE__, ##__VA_ARGS__)
49
49
  #define zkrb_debug_inst(O, M, ...) zkrb_debug("obj_id: %lx, " M, FIX2LONG(rb_obj_id(O)), ##__VA_ARGS__)
50
50
 
51
51
  // __dbg_h__
@@ -88,7 +88,8 @@ class ZookeeperBase
88
88
  update_pid! # from Forked
89
89
  end
90
90
  private :reopen_after_fork!
91
-
91
+
92
+
92
93
  def reopen(timeout = 10, watcher=nil)
93
94
  if watcher and (watcher != @default_watcher)
94
95
  raise "You cannot set the watcher to a different value this way anymore!"
@@ -97,11 +98,7 @@ class ZookeeperBase
97
98
  reopen_after_fork! if forked?
98
99
 
99
100
  @mutex.synchronize do
100
- if @czk
101
- @czk.close
102
- @czk = nil
103
- end
104
-
101
+ @czk.close if @czk
105
102
  @czk = CZookeeper.new(@host, @event_queue)
106
103
 
107
104
  # flushes all outstanding watcher reqs.
@@ -123,13 +120,14 @@ class ZookeeperBase
123
120
 
124
121
  @dispatcher = @czk = nil
125
122
 
123
+ update_pid!
126
124
  reopen_after_fork!
127
125
 
128
126
  # approximate the java behavior of raising java.lang.IllegalArgumentException if the host
129
127
  # argument ends with '/'
130
128
  raise ArgumentError, "Host argument #{host.inspect} may not end with /" if host.end_with?('/')
131
129
 
132
- @host = host
130
+ @host = host.dup
133
131
 
134
132
  @default_watcher = (watcher or get_default_global_watcher)
135
133
 
@@ -165,7 +163,7 @@ class ZookeeperBase
165
163
  shutdown_thread = Thread.new do
166
164
  @mutex.synchronize do
167
165
  stop_dispatch_thread!
168
- @czk.close
166
+ close!
169
167
  end
170
168
  end
171
169
 
data/ext/zookeeper_lib.c CHANGED
@@ -37,10 +37,34 @@ int ZKRBDebugging;
37
37
  // XXX(slyphon): need to check these for error, but what to do if they fail?
38
38
  pthread_mutex_t zkrb_q_mutex = PTHREAD_MUTEX_INITIALIZER;
39
39
 
40
- #define LOG_PTHREAD_ERR(A, M, ...) if (A) { log_err(M, ##__VA_ARGS__); errno=0; }
40
+ inline static int global_mutex_lock() {
41
+ int rv = pthread_mutex_lock(&zkrb_q_mutex);
42
+ if (rv != 0) log_err("global_mutex_lock error");
43
+ return rv;
44
+ }
41
45
 
42
- #define GLOBAL_MUTEX_LOCK(F) LOG_PTHREAD_ERR(pthread_mutex_lock(&zkrb_q_mutex), F)
43
- #define GLOBAL_MUTEX_UNLOCK(F) LOG_PTHREAD_ERR(pthread_mutex_unlock(&zkrb_q_mutex), F)
46
+ inline static int global_mutex_unlock() {
47
+ int rv = pthread_mutex_unlock(&zkrb_q_mutex);
48
+ if (rv != 0) log_err("global_mutex_unlock error");
49
+ return rv;
50
+ }
51
+
52
+ void atfork_prepare() {
53
+ global_mutex_lock();
54
+ }
55
+
56
+ void atfork_parent() {
57
+ global_mutex_unlock();
58
+ }
59
+
60
+ void atfork_child() {
61
+ global_mutex_unlock();
62
+ }
63
+
64
+ // set up handlers to make sure the thread being forked holds the lock at the
65
+ // time the process is copied, then immediately unlock the mutex in both parent
66
+ // and children
67
+ pthread_atfork(atfork_prepare, atfork_parent, atfork_child);
44
68
 
45
69
 
46
70
  void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
@@ -54,7 +78,7 @@ void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
54
78
  return;
55
79
  }
56
80
 
57
- pthread_mutex_lock(&q->mutex);
81
+ global_mutex_lock();
58
82
 
59
83
  q->tail->event = elt;
60
84
  q->tail->next = (zkrb_event_ll_t *) malloc(sizeof(zkrb_event_ll_t));
@@ -64,7 +88,7 @@ void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
64
88
 
65
89
  ssize_t ret = write(q->pipe_write, "0", 1); /* Wake up Ruby listener */
66
90
 
67
- pthread_mutex_unlock(&q->mutex);
91
+ global_mutex_unlock();
68
92
 
69
93
  if (ret < 0) {
70
94
  log_err("write to queue (%p) pipe failed!\n", q);
@@ -81,13 +105,13 @@ zkrb_event_t * zkrb_peek(zkrb_queue_t *q) {
81
105
 
82
106
  if (!q) return NULL;
83
107
 
84
- pthread_mutex_lock(&q->mutex);
108
+ global_mutex_lock();
85
109
 
86
110
  if (q != NULL && q->head != NULL && q->head->event != NULL) {
87
111
  event = q->head->event;
88
112
  }
89
113
 
90
- pthread_mutex_unlock(&q->mutex);
114
+ global_mutex_unlock();
91
115
 
92
116
  return event;
93
117
  }
@@ -99,7 +123,7 @@ zkrb_event_t* zkrb_dequeue(zkrb_queue_t *q, int need_lock) {
99
123
  zkrb_event_ll_t *old_root = NULL;
100
124
 
101
125
  if (need_lock)
102
- pthread_mutex_lock(&q->mutex);
126
+ global_mutex_lock();
103
127
 
104
128
  if (!ZKRB_QUEUE_EMPTY(q)) {
105
129
  old_root = q->head;
@@ -108,7 +132,7 @@ zkrb_event_t* zkrb_dequeue(zkrb_queue_t *q, int need_lock) {
108
132
  }
109
133
 
110
134
  if (need_lock)
111
- pthread_mutex_unlock(&q->mutex);
135
+ global_mutex_unlock();
112
136
 
113
137
  free(old_root);
114
138
  return rv;
@@ -117,12 +141,12 @@ zkrb_event_t* zkrb_dequeue(zkrb_queue_t *q, int need_lock) {
117
141
  void zkrb_signal(zkrb_queue_t *q) {
118
142
  if (!q) return;
119
143
 
120
- pthread_mutex_lock(&q->mutex);
144
+ global_mutex_lock();
121
145
 
122
146
  if (!write(q->pipe_write, "0", 1)) /* Wake up Ruby listener */
123
147
  log_err("zkrb_signal: write to pipe failed, could not wake");
124
148
 
125
- pthread_mutex_unlock(&q->mutex);
149
+ global_mutex_unlock();
126
150
  }
127
151
 
128
152
  zkrb_event_ll_t *zkrb_event_ll_t_alloc(void) {
@@ -147,8 +171,6 @@ zkrb_queue_t *zkrb_queue_alloc(void) {
147
171
 
148
172
  rq->orig_pid = getpid();
149
173
 
150
- check(pthread_mutex_init(&rq->mutex, NULL) == 0, "pthread_mutex_init failed");
151
-
152
174
  rq->head = zkrb_event_ll_t_alloc();
153
175
  check_mem(rq->head);
154
176
 
@@ -175,8 +197,6 @@ void zkrb_queue_free(zkrb_queue_t *queue) {
175
197
  close(queue->pipe_read);
176
198
  close(queue->pipe_write);
177
199
 
178
- pthread_mutex_destroy(&queue->mutex);
179
-
180
200
  free(queue);
181
201
  }
182
202
 
data/ext/zookeeper_lib.h CHANGED
@@ -106,7 +106,6 @@ typedef struct {
106
106
  zkrb_event_ll_t *tail;
107
107
  int pipe_read;
108
108
  int pipe_write;
109
- pthread_mutex_t mutex;
110
109
  pid_t orig_pid;
111
110
  } zkrb_queue_t;
112
111
 
data/lib/zookeeper.rb CHANGED
@@ -5,12 +5,16 @@ require 'monitor'
5
5
  require 'forwardable'
6
6
  require 'logger'
7
7
 
8
- require 'backports'
9
-
10
8
  module Zookeeper
11
9
  # establishes the namespace
12
10
  end
13
11
 
12
+ require File.expand_path('../zookeeper/core_ext', __FILE__)
13
+
14
+ silence_warnings do
15
+ require 'backports'
16
+ end
17
+
14
18
  require_relative 'zookeeper/forked'
15
19
  require_relative 'zookeeper/latch'
16
20
  require_relative 'zookeeper/acls'
@@ -0,0 +1,30 @@
1
+ # @private
2
+ module ::Kernel
3
+ unless method_defined?(:silence_warnings)
4
+ def silence_warnings
5
+ with_warnings(nil) { yield }
6
+ end
7
+ end
8
+
9
+ unless method_defined?(:with_warnings)
10
+ def with_warnings(flag)
11
+ old_verbose, $VERBOSE = $VERBOSE, flag
12
+ yield
13
+ ensure
14
+ $VERBOSE = old_verbose
15
+ end
16
+ end
17
+ end
18
+
19
+ # @private
20
+ class ::Exception
21
+ unless method_defined?(:to_std_format)
22
+ def to_std_format
23
+ ary = ["#{self.class}: #{message}"]
24
+ ary.concat(backtrace || [])
25
+ ary.join("\n\t")
26
+ end
27
+ end
28
+ end
29
+
30
+
@@ -14,6 +14,6 @@ module Zookeeper
14
14
  def update_pid!
15
15
  self.original_pid = Process.pid
16
16
  end
17
- end
18
- end
17
+ end # Forked
18
+ end # Zookeeper
19
19
 
@@ -1,4 +1,4 @@
1
1
  module Zookeeper
2
- VERSION = '1.0.3'
2
+ VERSION = '1.0.4'
3
3
  DRIVER_VERSION = '3.3.5'
4
4
  end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'fork hooks' do
4
+ def safe_kill_process(signal, pid)
5
+ Process.kill(signal, pid)
6
+ rescue Errno::ESRCH
7
+ nil
8
+ end
9
+
10
+ after do
11
+ Zookeeper::Forked.clear!
12
+
13
+ if @pid
14
+ safe_kill_process('KILL', @pid)
15
+ end
16
+ end
17
+
18
+ describe 'fork with a block' do
19
+ it %[should call the after_fork_in_child hooks in the child] do
20
+ child_hook_called = false
21
+
22
+ hook_order = []
23
+
24
+ Zookeeper.prepare_for_fork { hook_order << :prepare }
25
+ Zookeeper.after_fork_in_parent { hook_order << :parent }
26
+ Zookeeper.after_fork_in_child { hook_order << :child }
27
+
28
+ @pid = fork do
29
+ unless hook_order.first == :prepare
30
+ $stderr.puts "hook order wrong! #{hook_order.inspect}"
31
+ exit! 2
32
+ end
33
+
34
+ unless hook_order.last == :child
35
+ $stderr.puts "hook order wrong! #{hook_order.inspect}"
36
+ exit! 3
37
+ end
38
+
39
+ exit! 0
40
+ end
41
+
42
+ hook_order.first.should == :prepare
43
+ hook_order.last.should == :parent
44
+
45
+ _, st = Process.wait2(@pid)
46
+ st.exitstatus.should == 0
47
+
48
+ st.should be_exited
49
+ st.should be_success
50
+ end
51
+ end
52
+ end
53
+
@@ -27,14 +27,31 @@ unless defined?(::JRUBY_VERSION)
27
27
 
28
28
  after do
29
29
  if @pid and process_alive?(@pid)
30
- Process.kill('TERM', @pid)
31
- p Process.wait2(@pid)
30
+ begin
31
+ Process.kill('KILL', @pid)
32
+ p Process.wait2(@pid)
33
+ rescue Errno::ESRCH
34
+ end
32
35
  end
33
36
 
34
37
  @zk.close if @zk and !@zk.closed?
35
38
  with_open_zk(connection_string) { |z| rm_rf(z, path) }
36
39
  end
37
40
 
41
+ def wait_for_child_safely(pid, timeout=5)
42
+ time_to_stop = Time.now + timeout
43
+
44
+ until Time.now > time_to_stop
45
+ if a = Process.wait2(@pid, Process::WNOHANG)
46
+ return a.last
47
+ else
48
+ sleep(0.01)
49
+ end
50
+ end
51
+
52
+ nil
53
+ end
54
+
38
55
  it %[should do the right thing and not fail] do
39
56
  @zk.wait_until_connected
40
57
 
@@ -68,13 +85,21 @@ unless defined?(::JRUBY_VERSION)
68
85
  exit!(0)
69
86
  end
70
87
 
71
- logger.debug { "waiting on child #{@pid}" }
88
+ event_waiter_th = Thread.new do
89
+ @latch.await(10) unless @event
90
+ @event
91
+ end
72
92
 
73
- @latch.await until @event
93
+ logger.debug { "waiting on child #{@pid}" }
74
94
 
75
- _, status = Process.wait2(@pid)
95
+ status = wait_for_child_safely(@pid)
96
+ raise "Child process did not exit, likely hung" unless status
76
97
 
98
+ status.should_not be_signaled
77
99
  status.should be_success
100
+
101
+ event_waiter_th.join(5).should == event_waiter_th
102
+ @event.should_not be nil
78
103
  end
79
104
  end
80
105
  end
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: 17
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 3
10
- version: 1.0.3
9
+ - 4
10
+ version: 1.0.4
11
11
  platform: java
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-09 00:00:00 Z
23
+ date: 2012-05-10 00:00:00 Z
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: backports
@@ -122,6 +122,7 @@ files:
122
122
  - lib/zookeeper/common/queue_with_pipe.rb
123
123
  - lib/zookeeper/compatibility.rb
124
124
  - lib/zookeeper/constants.rb
125
+ - lib/zookeeper/core_ext.rb
125
126
  - lib/zookeeper/em_client.rb
126
127
  - lib/zookeeper/exceptions.rb
127
128
  - lib/zookeeper/forked.rb
@@ -136,6 +137,7 @@ files:
136
137
  - spec/compatibilty_spec.rb
137
138
  - spec/default_watcher_spec.rb
138
139
  - spec/em_spec.rb
140
+ - spec/fork_hook_specs.rb
139
141
  - spec/forked_connection_spec.rb
140
142
  - spec/latch_spec.rb
141
143
  - spec/log4j.properties
@@ -187,6 +189,7 @@ test_files:
187
189
  - spec/compatibilty_spec.rb
188
190
  - spec/default_watcher_spec.rb
189
191
  - spec/em_spec.rb
192
+ - spec/fork_hook_specs.rb
190
193
  - spec/forked_connection_spec.rb
191
194
  - spec/latch_spec.rb
192
195
  - spec/log4j.properties