zookeeper 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/c_zookeeper.rb +21 -26
- data/ext/common.h +10 -0
- data/ext/zkrb.c +11 -5
- data/lib/zookeeper/continuation.rb +30 -8
- data/lib/zookeeper/version.rb +1 -1
- metadata +4 -4
data/ext/c_zookeeper.rb
CHANGED
@@ -156,7 +156,7 @@ class CZookeeper
|
|
156
156
|
|
157
157
|
def state
|
158
158
|
return ZOO_CLOSED_STATE if closed?
|
159
|
-
|
159
|
+
submit_and_block(:state)
|
160
160
|
end
|
161
161
|
|
162
162
|
# this implementation is gross, but i don't really see another way of doing it
|
@@ -176,13 +176,21 @@ class CZookeeper
|
|
176
176
|
connected?
|
177
177
|
end
|
178
178
|
|
179
|
-
|
180
179
|
private
|
181
180
|
# submits a job for processing
|
182
181
|
# blocks the caller until result has returned
|
183
182
|
def submit_and_block(meth, *args)
|
184
183
|
cnt = Continuation.new(meth, *args)
|
185
|
-
@reg.
|
184
|
+
@reg.lock
|
185
|
+
begin
|
186
|
+
if meth == :state
|
187
|
+
@reg.pending.unshift(cnt)
|
188
|
+
else
|
189
|
+
@reg.pending << cnt
|
190
|
+
end
|
191
|
+
ensure
|
192
|
+
@reg.unlock rescue nil
|
193
|
+
end
|
186
194
|
wake_event_loop!
|
187
195
|
cnt.value
|
188
196
|
end
|
@@ -232,10 +240,8 @@ class CZookeeper
|
|
232
240
|
|
233
241
|
# this is the main loop
|
234
242
|
until (@_shutting_down or @_closed or is_unrecoverable)
|
235
|
-
submit_pending_calls if @reg.
|
236
|
-
|
237
|
-
zkrb_iterate_event_loop # XXX: check rc here
|
238
|
-
# end
|
243
|
+
submit_pending_calls if @reg.anything_to_do?
|
244
|
+
zkrb_iterate_event_loop
|
239
245
|
iterate_event_delivery
|
240
246
|
end
|
241
247
|
|
@@ -260,31 +266,20 @@ class CZookeeper
|
|
260
266
|
end
|
261
267
|
|
262
268
|
def submit_pending_calls
|
263
|
-
|
264
|
-
# and the keys are always unique
|
269
|
+
calls = @reg.next_batch()
|
265
270
|
|
266
|
-
|
271
|
+
return if calls.empty?
|
267
272
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
end
|
274
|
-
|
275
|
-
return if pending.empty?
|
276
|
-
|
277
|
-
logger.debug { "#{self.class}##{__method__} " }
|
278
|
-
|
279
|
-
while cntn = pending.shift
|
280
|
-
cntn.submit(self)
|
281
|
-
@reg.in_flight[cntn.req_id] = cntn # in_flight is only ever touched by us
|
273
|
+
while cntn = calls.shift
|
274
|
+
cntn.submit(self) # this delivers state check results (and does other stuff)
|
275
|
+
if req_id = cntn.req_id # state checks will not have a req_id
|
276
|
+
@reg.in_flight[req_id] = cntn # in_flight is only ever touched by us
|
277
|
+
end
|
282
278
|
end
|
283
279
|
end
|
284
280
|
|
285
281
|
def wake_event_loop!
|
286
|
-
|
287
|
-
@pipe_write && @pipe_write.write("\001")
|
282
|
+
@pipe_write && @pipe_write.write('1')
|
288
283
|
end
|
289
284
|
|
290
285
|
def iterate_event_delivery
|
data/ext/common.h
CHANGED
@@ -1,7 +1,17 @@
|
|
1
1
|
#ifndef ZKRB_COMMON_H
|
2
2
|
#define ZKRB_COMMON_H
|
3
3
|
|
4
|
+
#include "ruby.h"
|
5
|
+
|
4
6
|
//#define THREADED
|
5
7
|
#undef THREADED // we are linking against the zookeeper_st lib, this is crucial
|
6
8
|
|
9
|
+
#ifndef RB_GC_GUARD_PTR
|
10
|
+
#define RB_GC_GUARD_PTR(V) (V);
|
11
|
+
#endif
|
12
|
+
#ifndef RB_GC_GUARD
|
13
|
+
#define RB_GC_GUARD(V) (V);
|
14
|
+
#endif
|
15
|
+
|
16
|
+
|
7
17
|
#endif /* ZKRB_COMMON_H */
|
data/ext/zkrb.c
CHANGED
@@ -56,6 +56,13 @@
|
|
56
56
|
*
|
57
57
|
* NOTE: This file depends on exception classes defined in lib/zookeeper/exceptions.rb
|
58
58
|
*
|
59
|
+
* -------
|
60
|
+
*
|
61
|
+
* @rectalogic: any time you create a ruby value in C, and so there are no
|
62
|
+
* references to it in the VM except for your variable, and you then call into
|
63
|
+
* the VM (allowing a GC), and your reference is on the stack, then it needs to
|
64
|
+
* be volatile
|
65
|
+
*
|
59
66
|
*/
|
60
67
|
|
61
68
|
#include "ruby.h"
|
@@ -269,7 +276,7 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
|
|
269
276
|
zoo_set_debug_level(FIX2INT(log_level));
|
270
277
|
}
|
271
278
|
|
272
|
-
VALUE data;
|
279
|
+
volatile VALUE data;
|
273
280
|
zkrb_instance_data_t *zk_local_ctx;
|
274
281
|
data = Data_Make_Struct(CZookeeper, zkrb_instance_data_t, 0, free_zkrb_instance_data, zk_local_ctx);
|
275
282
|
|
@@ -665,13 +672,12 @@ static VALUE method_zkrb_get_next_event(VALUE self, VALUE blocking) {
|
|
665
672
|
check_debug(!is_closed(self), "we're closed in the middle of method_zkrb_get_next_event, bailing");
|
666
673
|
|
667
674
|
zkrb_event_t *event = zkrb_dequeue(zk->queue, 1);
|
668
|
-
|
669
|
-
/* Wait for an event using rb_thread_select() on the queue's pipe */
|
675
|
+
|
670
676
|
if (event == NULL) {
|
671
677
|
if (NIL_P(blocking) || (blocking == Qfalse)) {
|
672
678
|
goto error;
|
673
679
|
}
|
674
|
-
else {
|
680
|
+
else {
|
675
681
|
// if we're shutting down, don't enter this section, we don't want to block
|
676
682
|
check_debug(!is_shutting_down(self), "method_zkrb_get_next_event, we're shutting down, don't enter blocking section");
|
677
683
|
|
@@ -707,7 +713,7 @@ static VALUE method_zkrb_get_next_event(VALUE self, VALUE blocking) {
|
|
707
713
|
// the single threaded version of this call. will go away when we do direct
|
708
714
|
// event delivery (soon)
|
709
715
|
static VALUE method_zkrb_get_next_event_st(VALUE self) {
|
710
|
-
VALUE rval = Qnil;
|
716
|
+
volatile VALUE rval = Qnil;
|
711
717
|
|
712
718
|
if (is_closed(self)) {
|
713
719
|
zkrb_debug("we are closed, not gonna try to get an event");
|
@@ -8,6 +8,10 @@ module Zookeeper
|
|
8
8
|
|
9
9
|
# for keeping track of which continuations are pending, and which ones have
|
10
10
|
# been submitted and are awaiting a repsonse
|
11
|
+
#
|
12
|
+
# `state_check` are high-priority checks that query the connection about
|
13
|
+
# its current state, they always run before other continuations
|
14
|
+
#
|
11
15
|
class Registry < Struct.new(:pending, :in_flight)
|
12
16
|
extend Forwardable
|
13
17
|
|
@@ -23,15 +27,26 @@ module Zookeeper
|
|
23
27
|
begin
|
24
28
|
yield self
|
25
29
|
ensure
|
26
|
-
@mutex.unlock
|
30
|
+
@mutex.unlock rescue nil
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
30
34
|
# does not lock the mutex, returns true if there are pending jobs
|
31
|
-
def
|
32
|
-
!
|
35
|
+
def anything_to_do?
|
36
|
+
!pending.empty?
|
33
37
|
end
|
34
|
-
|
38
|
+
|
39
|
+
# returns the pending continuations, resetting the list
|
40
|
+
# this method is synchronized
|
41
|
+
def next_batch()
|
42
|
+
@mutex.lock
|
43
|
+
begin
|
44
|
+
pending.slice!(0,pending.length)
|
45
|
+
ensure
|
46
|
+
@mutex.unlock rescue nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end # Registry
|
35
50
|
|
36
51
|
# *sigh* what is the index in the *args array of the 'callback' param
|
37
52
|
CALLBACK_ARG_IDX = {
|
@@ -43,6 +58,7 @@ module Zookeeper
|
|
43
58
|
:get_acl => 2,
|
44
59
|
:set_acl => 3,
|
45
60
|
:get_children => 2,
|
61
|
+
:state => 0,
|
46
62
|
}
|
47
63
|
|
48
64
|
# maps the method name to the async return hash keys it should use to
|
@@ -111,9 +127,10 @@ module Zookeeper
|
|
111
127
|
def submit(czk)
|
112
128
|
rc, *_ = czk.__send__(:"zkrb_#{@meth}", *async_args)
|
113
129
|
|
114
|
-
|
115
|
-
|
116
|
-
|
130
|
+
# if this is an state call, async call, or we failed to submit it
|
131
|
+
if (@meth == :state) or user_callback? or (rc != ZOK)
|
132
|
+
@rval = [rc] # create the repsonse
|
133
|
+
deliver! # wake the caller and we're out
|
117
134
|
end
|
118
135
|
end
|
119
136
|
|
@@ -121,11 +138,16 @@ module Zookeeper
|
|
121
138
|
@args.first
|
122
139
|
end
|
123
140
|
|
141
|
+
def state_call?
|
142
|
+
@meth == :state
|
143
|
+
end
|
144
|
+
|
124
145
|
protected
|
125
146
|
|
126
147
|
# an args array with the only difference being that if there's a user
|
127
148
|
# callback provided, we don't handle delivering the end result
|
128
149
|
def async_args
|
150
|
+
return [] if @meth == :state # special-case :P
|
129
151
|
ary = @args.dup
|
130
152
|
|
131
153
|
logger.debug { "async_args, meth: #{meth} ary: #{ary.inspect}, #{callback_arg_idx}" }
|
@@ -147,7 +169,7 @@ module Zookeeper
|
|
147
169
|
begin
|
148
170
|
@cond.signal
|
149
171
|
ensure
|
150
|
-
@mutex.unlock
|
172
|
+
@mutex.unlock rescue nil
|
151
173
|
end
|
152
174
|
end
|
153
175
|
end # Base
|
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: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 1.1.
|
9
|
+
- 2
|
10
|
+
version: 1.1.2
|
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-17 00:00:00 Z
|
24
24
|
dependencies:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: backports
|