zookeeper 1.0.6-java → 1.1.0-java
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/.dotfiles/rvmrc +1 -0
- data/.travis.yml +5 -0
- data/CHANGELOG +13 -0
- data/Gemfile +3 -0
- data/Guardfile +6 -0
- data/README.markdown +16 -12
- data/Rakefile +5 -0
- data/cause-abort.rb +117 -0
- data/ext/Rakefile +34 -21
- data/ext/c_zookeeper.rb +181 -70
- data/ext/common.h +7 -0
- data/ext/depend +2 -2
- data/ext/{zookeeper_lib.c → event_lib.c} +107 -66
- data/ext/{zookeeper_lib.h → event_lib.h} +4 -3
- data/ext/extconf.rb +12 -8
- data/ext/generate_gvl_code.rb +9 -2
- data/ext/{zookeeper_c.c → zkrb.c} +415 -176
- data/ext/zookeeper_base.rb +7 -26
- data/lib/zookeeper/client_methods.rb +1 -1
- data/lib/zookeeper/common.rb +3 -2
- data/lib/zookeeper/constants.rb +1 -0
- data/lib/zookeeper/continuation.rb +155 -0
- data/lib/zookeeper/exceptions.rb +7 -0
- data/lib/zookeeper/logger.rb +7 -0
- data/lib/zookeeper/monitor.rb +19 -0
- data/lib/zookeeper/version.rb +1 -1
- data/lib/zookeeper.rb +3 -0
- data/spec/forked_connection_spec.rb +11 -4
- data/spec/shared/connection_examples.rb +24 -22
- data/spec/spec_helper.rb +2 -2
- data/spec/support/zookeeper_spec_helpers.rb +1 -1
- metadata +12 -9
- data/spec/fork_hook_specs.rb +0 -53
@@ -8,11 +8,64 @@
|
|
8
8
|
* approach to isolate the ZK state machine from the ruby interpreter via an
|
9
9
|
* event queue. It's similar to the ZookeeperFFI version except that it
|
10
10
|
* actually works on MRI 1.8.
|
11
|
+
*
|
12
|
+
*----------------
|
13
|
+
* (slyphon)
|
14
|
+
*
|
15
|
+
* Wickman's implementation was linked against the 'mt' version of the zookeeper
|
16
|
+
* library, which is multithreaded at the zookeeper level and is subsequently
|
17
|
+
* much more difficult to get to behave properly with the ruby runtime (which
|
18
|
+
* he did, and I could never have written).
|
19
|
+
*
|
20
|
+
* The current implementation has been converted to use the 'st' version of the
|
21
|
+
* zookeeper library, which is single threaded and requires a ruby-side event
|
22
|
+
* loop. This is essentially a ruby port of the code running in the 'mt'
|
23
|
+
* library, with one important difference: It's running in ruby-land. The
|
24
|
+
* reason this change is so important is that it's virtually impossible to
|
25
|
+
* provide a fork-safe library when you have native threads you don't own
|
26
|
+
* running around. If you fork when a thread holds a mutex, and that thread
|
27
|
+
* is not the fork-caller, that mutex can never be unlocked, and is therefore
|
28
|
+
* a ticking time-bomb in the child. The only way to guarantee safety is to
|
29
|
+
* either replace all of your mutexes and conditions and such after a fork
|
30
|
+
* (which is what we do on the ruby side), or avoid the problem altogether
|
31
|
+
* and not use a multithreaded library on the backend. Since we can't replace
|
32
|
+
* mutexes in the zookeeper code, we opt for the latter solution.
|
33
|
+
*
|
34
|
+
* The ruby code runs the event loop in a thread that will never cause a fork()
|
35
|
+
* to occur. This way, when fork() is called, the event thread will be dead
|
36
|
+
* in the child, guaranteeing that the child can safely be cleaned up.
|
37
|
+
*
|
38
|
+
* In that cleanup, there is a nasty (and brutishly effective) hack that makes
|
39
|
+
* the fork case work. We keep track of the pid that allocated the
|
40
|
+
* zkrb_instance_data_t, and if at destruction time we see that a fork has
|
41
|
+
* happened, we reach inside the zookeeper handle (zk->zh), and close the
|
42
|
+
* open socket it's got before calling zookeeper_close. This prevents
|
43
|
+
* corruption of the client/server state. Without this code, zookeeper_close
|
44
|
+
* in the child would actually send an "Ok, we're closing" message with the
|
45
|
+
* parent's session id, causing the parent to hit an assert() case in
|
46
|
+
* zookeeper_process, and cause a SIGABRT. With this code in place, we get back
|
47
|
+
* a ZCONNECTIONLOSS from zookeeper_close in the child (which we ignore), and
|
48
|
+
* the parent continues on.
|
49
|
+
*
|
50
|
+
* You will notice below we undef 'THREADED', which would be set if we were
|
51
|
+
* using the 'mt' library. We also conditionally include additional cases
|
52
|
+
* ('SYNC', 'SYNC_WATCH') inside of some of the methods defined here. These
|
53
|
+
* would be valid when running the 'mt' library, but since we have a ruby layer
|
54
|
+
* to provide a sync front-end to an async backend, these cases should never be
|
55
|
+
* hit, and instead will raise exceptions.
|
56
|
+
*
|
57
|
+
* NOTE: This file depends on exception classes defined in lib/zookeeper/exceptions.rb
|
58
|
+
*
|
11
59
|
*/
|
12
60
|
|
13
|
-
#define THREADED
|
14
|
-
|
15
61
|
#include "ruby.h"
|
62
|
+
|
63
|
+
#ifdef ZKRB_RUBY_187
|
64
|
+
#include "rubyio.h"
|
65
|
+
#else
|
66
|
+
#include "ruby/io.h"
|
67
|
+
#endif
|
68
|
+
|
16
69
|
#include "c-client-src/zookeeper.h"
|
17
70
|
#include <errno.h>
|
18
71
|
#include <stdio.h>
|
@@ -21,15 +74,18 @@
|
|
21
74
|
#include <sys/fcntl.h>
|
22
75
|
#include <pthread.h>
|
23
76
|
#include <inttypes.h>
|
77
|
+
#include <time.h>
|
24
78
|
|
25
|
-
#include "
|
79
|
+
#include "common.h"
|
80
|
+
#include "event_lib.h"
|
26
81
|
#include "zkrb_wrapper.h"
|
27
82
|
#include "dbg.h"
|
28
83
|
|
29
|
-
|
30
84
|
static VALUE mZookeeper = Qnil; // the Zookeeper module
|
31
85
|
static VALUE CZookeeper = Qnil; // the Zookeeper::CZookeeper class
|
32
86
|
static VALUE ZookeeperClientId = Qnil;
|
87
|
+
static VALUE mZookeeperExceptions = Qnil; // the Zookeeper::Exceptions module
|
88
|
+
static VALUE eHandleClosedException = Qnil; // raised when we don't have a valid handle in FETCH_DATA_PTR
|
33
89
|
|
34
90
|
// slyphon: possibly add a lock to this for synchronizing during get_next_event
|
35
91
|
|
@@ -41,6 +97,8 @@ struct zkrb_instance_data {
|
|
41
97
|
pid_t orig_pid;
|
42
98
|
};
|
43
99
|
|
100
|
+
typedef struct zkrb_instance_data zkrb_instance_data_t;
|
101
|
+
|
44
102
|
typedef enum {
|
45
103
|
SYNC = 0,
|
46
104
|
ASYNC = 1,
|
@@ -48,41 +106,109 @@ typedef enum {
|
|
48
106
|
ASYNC_WATCH = 3
|
49
107
|
} zkrb_call_type;
|
50
108
|
|
109
|
+
inline static const char* call_type_to_str(zkrb_call_type ct) {
|
110
|
+
switch (ct) {
|
111
|
+
case SYNC:
|
112
|
+
return "SYNC";
|
113
|
+
case ASYNC:
|
114
|
+
return "ASYNC";
|
115
|
+
case SYNC_WATCH:
|
116
|
+
return "SYNC_WATCH";
|
117
|
+
case ASYNC_WATCH:
|
118
|
+
return "ASYNC_WATCH";
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
inline static void assert_valid_params(VALUE reqid, VALUE path) {
|
123
|
+
switch (TYPE(reqid)) {
|
124
|
+
case T_FIXNUM:
|
125
|
+
case T_BIGNUM:
|
126
|
+
break;
|
127
|
+
default:
|
128
|
+
rb_raise(rb_eTypeError, "reqid must be Fixnum/Bignum");
|
129
|
+
}
|
130
|
+
|
131
|
+
Check_Type(path, T_STRING);
|
132
|
+
}
|
133
|
+
|
134
|
+
inline static zkrb_call_type get_call_type(VALUE async, VALUE watch) {
|
135
|
+
if RTEST(async) {
|
136
|
+
return RTEST(watch) ? ASYNC_WATCH : ASYNC;
|
137
|
+
} else {
|
138
|
+
return RTEST(watch) ? SYNC_WATCH : SYNC;
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
inline static void raise_invalid_call_type_err(zkrb_call_type call_type) {
|
143
|
+
rb_raise(rb_eRuntimeError, "hit the default case, call_type: %s", call_type_to_str(call_type));
|
144
|
+
}
|
145
|
+
|
51
146
|
#define IS_SYNC(zkrbcall) ((zkrbcall)==SYNC || (zkrbcall)==SYNC_WATCH)
|
52
147
|
#define IS_ASYNC(zkrbcall) ((zkrbcall)==ASYNC || (zkrbcall)==ASYNC_WATCH)
|
53
148
|
|
149
|
+
#define FETCH_DATA_PTR(SELF, ZK) \
|
150
|
+
zkrb_instance_data_t * ZK; \
|
151
|
+
Data_Get_Struct(rb_iv_get(SELF, "@_data"), zkrb_instance_data_t, ZK); \
|
152
|
+
if ((ZK)->zh == NULL) \
|
153
|
+
rb_raise(eHandleClosedException, "zookeeper handle is closed")
|
154
|
+
|
155
|
+
#define STANDARD_PREAMBLE(SELF, ZK, REQID, PATH, ASYNC, WATCH, CALL_TYPE) \
|
156
|
+
assert_valid_params(REQID, PATH); \
|
157
|
+
FETCH_DATA_PTR(SELF, ZK); \
|
158
|
+
zkrb_call_type CALL_TYPE = get_call_type(ASYNC, WATCH); \
|
54
159
|
|
55
|
-
|
160
|
+
#define CTX_ALLOC(ZK,REQID) zkrb_calling_context_alloc(NUM2LL(REQID), ZK->queue)
|
161
|
+
|
162
|
+
static void hexbufify(char *dest, const char *src, int len) {
|
163
|
+
int i=0;
|
164
|
+
|
165
|
+
for (i=0; i < len; i++) {
|
166
|
+
sprintf(&dest[i*2], "%x", src[i]);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
static int destroy_zkrb_instance(zkrb_instance_data_t* zk) {
|
56
171
|
int rv = ZOK;
|
57
172
|
|
58
|
-
zkrb_debug("destroy_zkrb_instance, zk_local_ctx: %p, zh: %p, queue: %p",
|
173
|
+
zkrb_debug("destroy_zkrb_instance, zk_local_ctx: %p, zh: %p, queue: %p", zk, zk->zh, zk->queue);
|
59
174
|
|
60
|
-
if (
|
61
|
-
const void *ctx = zoo_get_context(
|
175
|
+
if (zk->zh) {
|
176
|
+
const void *ctx = zoo_get_context(zk->zh);
|
62
177
|
/* Note that after zookeeper_close() returns, ZK handle is invalid */
|
63
|
-
zkrb_debug("obj_id: %lx, calling zookeeper_close",
|
64
|
-
|
65
|
-
|
66
|
-
|
178
|
+
zkrb_debug("obj_id: %lx, calling zookeeper_close", zk->object_id);
|
179
|
+
|
180
|
+
if (zk->orig_pid != getpid()) {
|
181
|
+
zkrb_debug("FORK DETECTED! orig_pid: %d, current pid: %d, "
|
182
|
+
"using socket-closing hack before zookeeper_close", zk->orig_pid, getpid());
|
183
|
+
|
184
|
+
int fd = ((int *)zk->zh)[0]; // nasty, brutish, and wonderfully effective hack (see above)
|
185
|
+
close(fd);
|
186
|
+
}
|
187
|
+
|
188
|
+
rv = zookeeper_close(zk->zh);
|
189
|
+
|
190
|
+
zkrb_debug("obj_id: %lx, zookeeper_close returned %d", zk->object_id, rv);
|
191
|
+
zkrb_calling_context_free((zkrb_calling_context *) ctx);
|
67
192
|
}
|
68
193
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
194
|
+
zk->zh = NULL;
|
195
|
+
|
196
|
+
// [wickman] TODO: fire off warning if queue is not empty
|
197
|
+
if (zk->queue) {
|
198
|
+
zkrb_debug("obj_id: %lx, freeing queue pointer: %p", zk->object_id, zk->queue);
|
199
|
+
zkrb_queue_free(zk->queue);
|
73
200
|
}
|
74
201
|
|
75
|
-
|
76
|
-
ptr->queue = NULL;
|
202
|
+
zk->queue = NULL;
|
77
203
|
|
78
204
|
return rv;
|
79
205
|
}
|
80
206
|
|
81
|
-
static void free_zkrb_instance_data(
|
207
|
+
static void free_zkrb_instance_data(zkrb_instance_data_t* ptr) {
|
82
208
|
destroy_zkrb_instance(ptr);
|
83
209
|
}
|
84
210
|
|
85
|
-
static void print_zkrb_instance_data(
|
211
|
+
static void print_zkrb_instance_data(zkrb_instance_data_t* ptr) {
|
86
212
|
fprintf(stderr, "zkrb_instance_data (%p) {\n", ptr);
|
87
213
|
fprintf(stderr, " zh = %p\n", ptr->zh);
|
88
214
|
fprintf(stderr, " { state = %d }\n", zoo_state(ptr->zh));
|
@@ -92,52 +218,16 @@ static void print_zkrb_instance_data(struct zkrb_instance_data* ptr) {
|
|
92
218
|
fprintf(stderr, "}\n");
|
93
219
|
}
|
94
220
|
|
95
|
-
|
96
|
-
static VALUE zkrb_new_instance _((VALUE));
|
97
|
-
|
98
|
-
static VALUE zkrb_new_instance(VALUE args) {
|
99
|
-
return rb_class_new_instance(2, (VALUE*)args+1, *(VALUE*)args);
|
100
|
-
}
|
101
|
-
|
102
|
-
static int zkrb_dup(int orig) {
|
103
|
-
int fd;
|
104
|
-
|
105
|
-
fd = dup(orig);
|
106
|
-
if (fd < 0) {
|
107
|
-
if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {
|
108
|
-
rb_gc();
|
109
|
-
fd = dup(orig);
|
110
|
-
}
|
111
|
-
if (fd < 0) {
|
112
|
-
rb_sys_fail(0);
|
113
|
-
}
|
114
|
-
}
|
115
|
-
return fd;
|
116
|
-
}
|
117
|
-
|
118
|
-
#if 0
|
119
|
-
static VALUE create_selectable_io(zkrb_queue_t *q) {
|
120
|
-
// rb_cIO is the ruby IO class?
|
121
|
-
|
122
|
-
int pipe, state, read_fd;
|
123
|
-
VALUE args[3], reader;
|
124
|
-
|
125
|
-
read_fd = zkrb_dup(q->pipe_read);
|
126
|
-
|
127
|
-
args[0] = rb_cIO;
|
128
|
-
args[1] = INT2NUM(read_fd);
|
129
|
-
args[2] = INT2FIX(O_RDONLY);
|
130
|
-
reader = rb_protect(zkrb_new_instance, (VALUE)args, &state);
|
221
|
+
#define session_timeout_msec(self) rb_iv_get(self, "@_session_timeout_msec")
|
131
222
|
|
132
|
-
|
133
|
-
|
134
|
-
|
223
|
+
inline static void zkrb_debug_clientid_t(const clientid_t *cid) {
|
224
|
+
int pass_len = sizeof(cid->passwd);
|
225
|
+
int hex_len = 2 * pass_len;
|
226
|
+
char buf[hex_len];
|
227
|
+
hexbufify(buf, cid->passwd, pass_len);
|
135
228
|
|
136
|
-
|
229
|
+
zkrb_debug("myid, client_id: %"PRId64", passwd: %*s", cid->client_id, hex_len, buf);
|
137
230
|
}
|
138
|
-
#endif
|
139
|
-
|
140
|
-
#define session_timeout_msec(self) rb_iv_get(self, "@_session_timeout_msec")
|
141
231
|
|
142
232
|
static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
|
143
233
|
VALUE hostPort;
|
@@ -163,8 +253,8 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
|
|
163
253
|
}
|
164
254
|
|
165
255
|
VALUE data;
|
166
|
-
|
167
|
-
data = Data_Make_Struct(CZookeeper,
|
256
|
+
zkrb_instance_data_t *zk_local_ctx;
|
257
|
+
data = Data_Make_Struct(CZookeeper, zkrb_instance_data_t, 0, free_zkrb_instance_data, zk_local_ctx);
|
168
258
|
|
169
259
|
zk_local_ctx->queue = zkrb_queue_alloc();
|
170
260
|
|
@@ -190,7 +280,6 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
|
|
190
280
|
zkrb_debug("method_zkrb_init, zk_local_ctx: %p, zh: %p, queue: %p, calling_ctx: %p",
|
191
281
|
zk_local_ctx, zk_local_ctx->zh, zk_local_ctx->queue, ctx);
|
192
282
|
|
193
|
-
#warning [wickman] TODO handle this properly on the Ruby side rather than C side
|
194
283
|
if (!zk_local_ctx->zh) {
|
195
284
|
rb_raise(rb_eRuntimeError, "error connecting to zookeeper: %d", errno);
|
196
285
|
}
|
@@ -200,66 +289,47 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
|
|
200
289
|
rb_iv_set(self, "@_data", data);
|
201
290
|
rb_funcall(self, rb_intern("zkc_set_running_and_notify!"), 0);
|
202
291
|
|
203
|
-
error:
|
204
292
|
return Qnil;
|
205
293
|
}
|
206
294
|
|
207
|
-
#define FETCH_DATA_PTR(X, Y) \
|
208
|
-
struct zkrb_instance_data * Y; \
|
209
|
-
Data_Get_Struct(rb_iv_get(X, "@_data"), struct zkrb_instance_data, Y); \
|
210
|
-
if ((Y)->zh == NULL) \
|
211
|
-
rb_raise(rb_eRuntimeError, "zookeeper handle is closed")
|
212
|
-
|
213
|
-
#define STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, cb_ctx, w_ctx, call_type) \
|
214
|
-
if (TYPE(reqid) != T_FIXNUM && TYPE(reqid) != T_BIGNUM) { \
|
215
|
-
rb_raise(rb_eTypeError, "reqid must be Fixnum/Bignum"); \
|
216
|
-
return Qnil; \
|
217
|
-
} \
|
218
|
-
Check_Type(path, T_STRING); \
|
219
|
-
struct zkrb_instance_data * zk; \
|
220
|
-
Data_Get_Struct(rb_iv_get(self, "@_data"), struct zkrb_instance_data, zk); \
|
221
|
-
if (!zk->zh) \
|
222
|
-
rb_raise(rb_eRuntimeError, "zookeeper handle is closed"); \
|
223
|
-
zkrb_calling_context* cb_ctx = \
|
224
|
-
(async != Qfalse && async != Qnil) ? \
|
225
|
-
zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) : \
|
226
|
-
NULL; \
|
227
|
-
zkrb_calling_context* w_ctx = \
|
228
|
-
(watch != Qfalse && watch != Qnil) ? \
|
229
|
-
zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) : \
|
230
|
-
NULL; \
|
231
|
-
int a_ = (async != Qfalse && async != Qnil); \
|
232
|
-
int w_ = (watch != Qfalse && watch != Qnil); \
|
233
|
-
zkrb_call_type call_type; \
|
234
|
-
if (a_) { if (w_) { call_type = ASYNC_WATCH; } else { call_type = ASYNC; } } \
|
235
|
-
else { if (w_) { call_type = SYNC_WATCH; } else { call_type = SYNC; } }
|
236
|
-
|
237
295
|
static VALUE method_get_children(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE watch) {
|
238
|
-
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch,
|
296
|
+
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, call_type);
|
239
297
|
|
298
|
+
VALUE output = Qnil;
|
240
299
|
struct String_vector strings;
|
241
300
|
struct Stat stat;
|
242
301
|
|
243
302
|
int rc;
|
244
303
|
switch (call_type) {
|
304
|
+
|
305
|
+
#ifdef THREADED
|
245
306
|
case SYNC:
|
246
|
-
rc = zkrb_call_zoo_get_children2(
|
307
|
+
rc = zkrb_call_zoo_get_children2(
|
308
|
+
zk->zh, RSTRING_PTR(path), 0, &strings, &stat);
|
247
309
|
break;
|
248
310
|
|
249
311
|
case SYNC_WATCH:
|
250
|
-
rc = zkrb_call_zoo_wget_children2(
|
312
|
+
rc = zkrb_call_zoo_wget_children2(
|
313
|
+
zk->zh, RSTRING_PTR(path), zkrb_state_callback, CTX_ALLOC(zk, reqid), &strings, &stat);
|
251
314
|
break;
|
315
|
+
#endif
|
252
316
|
|
253
317
|
case ASYNC:
|
254
|
-
rc = zkrb_call_zoo_aget_children2(
|
318
|
+
rc = zkrb_call_zoo_aget_children2(
|
319
|
+
zk->zh, RSTRING_PTR(path), 0, zkrb_strings_stat_callback, CTX_ALLOC(zk, reqid));
|
255
320
|
break;
|
256
321
|
|
257
322
|
case ASYNC_WATCH:
|
258
|
-
rc = zkrb_call_zoo_awget_children2(
|
323
|
+
rc = zkrb_call_zoo_awget_children2(
|
324
|
+
zk->zh, RSTRING_PTR(path), zkrb_state_callback, CTX_ALLOC(zk, reqid), zkrb_strings_stat_callback, CTX_ALLOC(zk, reqid));
|
325
|
+
break;
|
326
|
+
|
327
|
+
default:
|
328
|
+
raise_invalid_call_type_err(call_type);
|
259
329
|
break;
|
260
330
|
}
|
261
331
|
|
262
|
-
|
332
|
+
output = rb_ary_new();
|
263
333
|
rb_ary_push(output, INT2FIX(rc));
|
264
334
|
if (IS_SYNC(call_type) && rc == ZOK) {
|
265
335
|
rb_ary_push(output, zkrb_string_vector_to_ruby(&strings));
|
@@ -269,30 +339,38 @@ static VALUE method_get_children(VALUE self, VALUE reqid, VALUE path, VALUE asyn
|
|
269
339
|
}
|
270
340
|
|
271
341
|
static VALUE method_exists(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE watch) {
|
272
|
-
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch,
|
342
|
+
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, call_type);
|
273
343
|
|
344
|
+
VALUE output = Qnil;
|
274
345
|
struct Stat stat;
|
275
346
|
|
276
347
|
int rc;
|
277
348
|
switch (call_type) {
|
349
|
+
|
350
|
+
#ifdef THREADED
|
278
351
|
case SYNC:
|
279
352
|
rc = zkrb_call_zoo_exists(zk->zh, RSTRING_PTR(path), 0, &stat);
|
280
353
|
break;
|
281
354
|
|
282
355
|
case SYNC_WATCH:
|
283
|
-
rc = zkrb_call_zoo_wexists(zk->zh, RSTRING_PTR(path), zkrb_state_callback,
|
356
|
+
rc = zkrb_call_zoo_wexists(zk->zh, RSTRING_PTR(path), zkrb_state_callback, CTX_ALLOC(zk, reqid), &stat);
|
284
357
|
break;
|
358
|
+
#endif
|
285
359
|
|
286
360
|
case ASYNC:
|
287
|
-
rc = zkrb_call_zoo_aexists(zk->zh, RSTRING_PTR(path), 0, zkrb_stat_callback,
|
361
|
+
rc = zkrb_call_zoo_aexists(zk->zh, RSTRING_PTR(path), 0, zkrb_stat_callback, CTX_ALLOC(zk, reqid));
|
288
362
|
break;
|
289
363
|
|
290
364
|
case ASYNC_WATCH:
|
291
|
-
rc = zkrb_call_zoo_awexists(zk->zh, RSTRING_PTR(path), zkrb_state_callback,
|
365
|
+
rc = zkrb_call_zoo_awexists(zk->zh, RSTRING_PTR(path), zkrb_state_callback, CTX_ALLOC(zk, reqid), zkrb_stat_callback, CTX_ALLOC(zk, reqid));
|
366
|
+
break;
|
367
|
+
|
368
|
+
default:
|
369
|
+
raise_invalid_call_type_err(call_type);
|
292
370
|
break;
|
293
371
|
}
|
294
372
|
|
295
|
-
|
373
|
+
output = rb_ary_new();
|
296
374
|
rb_ary_push(output, INT2FIX(rc));
|
297
375
|
if (IS_SYNC(call_type) && rc == ZOK) {
|
298
376
|
rb_ary_push(output, zkrb_stat_to_rarray(&stat));
|
@@ -302,20 +380,21 @@ static VALUE method_exists(VALUE self, VALUE reqid, VALUE path, VALUE async, VAL
|
|
302
380
|
|
303
381
|
// this method is *only* called asynchronously
|
304
382
|
static VALUE method_sync(VALUE self, VALUE reqid, VALUE path) {
|
305
|
-
|
306
|
-
VALUE watch = Qfalse;
|
307
|
-
int rc;
|
383
|
+
int rc = ZOK;
|
308
384
|
|
309
|
-
STANDARD_PREAMBLE
|
385
|
+
// don't use STANDARD_PREAMBLE here b/c we don't need to determine call_type
|
386
|
+
assert_valid_params(reqid, path);
|
387
|
+
FETCH_DATA_PTR(self, zk);
|
310
388
|
|
311
|
-
rc = zkrb_call_zoo_async(zk->zh, RSTRING_PTR(path), zkrb_string_callback,
|
389
|
+
rc = zkrb_call_zoo_async(zk->zh, RSTRING_PTR(path), zkrb_string_callback, CTX_ALLOC(zk, reqid));
|
312
390
|
|
313
391
|
return INT2FIX(rc);
|
314
392
|
}
|
315
393
|
|
394
|
+
|
316
395
|
static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALUE async, VALUE acls, VALUE flags) {
|
317
|
-
|
318
|
-
|
396
|
+
STANDARD_PREAMBLE(self, zk, reqid, path, async, Qfalse, call_type);
|
397
|
+
VALUE output = Qnil;
|
319
398
|
|
320
399
|
if (data != Qnil) Check_Type(data, T_STRING);
|
321
400
|
Check_Type(flags, T_FIXNUM);
|
@@ -328,28 +407,29 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
|
|
328
407
|
|
329
408
|
int rc;
|
330
409
|
switch (call_type) {
|
410
|
+
|
411
|
+
#ifdef THREADED
|
331
412
|
case SYNC:
|
332
413
|
// casting data_len to int is OK as you can only store 1MB in zookeeper
|
333
414
|
rc = zkrb_call_zoo_create(zk->zh, RSTRING_PTR(path), data_ptr, (int)data_len, aclptr, FIX2INT(flags), realpath, sizeof(realpath));
|
334
|
-
|
335
415
|
break;
|
336
|
-
|
337
|
-
rc = zkrb_call_zoo_acreate(zk->zh, RSTRING_PTR(path), data_ptr, (int)data_len, aclptr, FIX2INT(flags), zkrb_string_callback, data_ctx);
|
416
|
+
#endif
|
338
417
|
|
418
|
+
case ASYNC:
|
419
|
+
rc = zkrb_call_zoo_acreate(zk->zh, RSTRING_PTR(path), data_ptr, (int)data_len, aclptr, FIX2INT(flags), zkrb_string_callback, CTX_ALLOC(zk, reqid));
|
339
420
|
break;
|
421
|
+
|
340
422
|
default:
|
341
|
-
|
342
|
-
return Qnil;
|
423
|
+
raise_invalid_call_type_err(call_type);
|
343
424
|
break;
|
344
425
|
}
|
345
426
|
|
346
|
-
|
347
427
|
if (aclptr) {
|
348
428
|
deallocate_ACL_vector(aclptr);
|
349
429
|
free(aclptr);
|
350
430
|
}
|
351
431
|
|
352
|
-
|
432
|
+
output = rb_ary_new();
|
353
433
|
rb_ary_push(output, INT2FIX(rc));
|
354
434
|
if (IS_SYNC(call_type) && rc == ZOK) {
|
355
435
|
return rb_ary_push(output, rb_str_new2(realpath));
|
@@ -358,21 +438,24 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
|
|
358
438
|
}
|
359
439
|
|
360
440
|
static VALUE method_delete(VALUE self, VALUE reqid, VALUE path, VALUE version, VALUE async) {
|
361
|
-
|
362
|
-
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, data_ctx, watch_ctx, call_type);
|
441
|
+
STANDARD_PREAMBLE(self, zk, reqid, path, async, Qfalse, call_type);
|
363
442
|
Check_Type(version, T_FIXNUM);
|
364
443
|
|
365
444
|
int rc = 0;
|
366
445
|
switch (call_type) {
|
446
|
+
|
447
|
+
#ifdef THREADED
|
367
448
|
case SYNC:
|
368
449
|
rc = zkrb_call_zoo_delete(zk->zh, RSTRING_PTR(path), FIX2INT(version));
|
369
450
|
break;
|
451
|
+
#endif
|
452
|
+
|
370
453
|
case ASYNC:
|
371
|
-
rc = zkrb_call_zoo_adelete(zk->zh, RSTRING_PTR(path), FIX2INT(version), zkrb_void_callback,
|
454
|
+
rc = zkrb_call_zoo_adelete(zk->zh, RSTRING_PTR(path), FIX2INT(version), zkrb_void_callback, CTX_ALLOC(zk, reqid));
|
372
455
|
break;
|
456
|
+
|
373
457
|
default:
|
374
|
-
|
375
|
-
return Qnil;
|
458
|
+
raise_invalid_call_type_err(call_type);
|
376
459
|
break;
|
377
460
|
}
|
378
461
|
|
@@ -382,34 +465,46 @@ static VALUE method_delete(VALUE self, VALUE reqid, VALUE path, VALUE version, V
|
|
382
465
|
#define MAX_ZNODE_SIZE 1048576
|
383
466
|
|
384
467
|
static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE watch) {
|
385
|
-
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch,
|
468
|
+
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, call_type);
|
469
|
+
|
470
|
+
VALUE output = Qnil;
|
386
471
|
|
387
|
-
/* ugh */
|
388
|
-
char * data = malloc(MAX_ZNODE_SIZE);
|
389
472
|
int data_len = MAX_ZNODE_SIZE;
|
390
473
|
struct Stat stat;
|
391
474
|
|
475
|
+
char * data = xmalloc(MAX_ZNODE_SIZE); /* ugh */
|
476
|
+
|
392
477
|
int rc;
|
393
478
|
|
394
479
|
switch (call_type) {
|
480
|
+
|
481
|
+
#ifdef THREADED
|
395
482
|
case SYNC:
|
396
483
|
rc = zkrb_call_zoo_get(zk->zh, RSTRING_PTR(path), 0, data, &data_len, &stat);
|
397
484
|
break;
|
398
485
|
|
399
486
|
case SYNC_WATCH:
|
400
|
-
rc = zkrb_call_zoo_wget(
|
487
|
+
rc = zkrb_call_zoo_wget(
|
488
|
+
zk->zh, RSTRING_PTR(path), zkrb_state_callback, CTX_ALLOC(zk, reqid), data, &data_len, &stat);
|
401
489
|
break;
|
490
|
+
#endif
|
402
491
|
|
403
492
|
case ASYNC:
|
404
|
-
rc = zkrb_call_zoo_aget(zk->zh, RSTRING_PTR(path), 0, zkrb_data_callback,
|
493
|
+
rc = zkrb_call_zoo_aget(zk->zh, RSTRING_PTR(path), 0, zkrb_data_callback, CTX_ALLOC(zk, reqid));
|
405
494
|
break;
|
406
495
|
|
407
496
|
case ASYNC_WATCH:
|
408
|
-
|
497
|
+
// first ctx is a watch, second is the async callback
|
498
|
+
rc = zkrb_call_zoo_awget(
|
499
|
+
zk->zh, RSTRING_PTR(path), zkrb_state_callback, CTX_ALLOC(zk, reqid), zkrb_data_callback, CTX_ALLOC(zk, reqid));
|
500
|
+
break;
|
501
|
+
|
502
|
+
default:
|
503
|
+
raise_invalid_call_type_err(call_type);
|
409
504
|
break;
|
410
505
|
}
|
411
506
|
|
412
|
-
|
507
|
+
output = rb_ary_new();
|
413
508
|
rb_ary_push(output, INT2FIX(rc));
|
414
509
|
if (IS_SYNC(call_type) && rc == ZOK) {
|
415
510
|
if (data_len == -1)
|
@@ -418,36 +513,42 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
|
|
418
513
|
rb_ary_push(output, rb_str_new(data, data_len));
|
419
514
|
rb_ary_push(output, zkrb_stat_to_rarray(&stat));
|
420
515
|
}
|
421
|
-
free(data);
|
422
516
|
|
517
|
+
xfree(data);
|
423
518
|
return output;
|
424
519
|
}
|
425
520
|
|
426
521
|
static VALUE method_set(VALUE self, VALUE reqid, VALUE path, VALUE data, VALUE async, VALUE version) {
|
427
|
-
|
428
|
-
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, data_ctx, watch_ctx, call_type);
|
522
|
+
STANDARD_PREAMBLE(self, zk, reqid, path, async, Qfalse, call_type);
|
429
523
|
|
524
|
+
VALUE output = Qnil;
|
430
525
|
struct Stat stat;
|
526
|
+
|
431
527
|
if (data != Qnil) Check_Type(data, T_STRING);
|
528
|
+
|
432
529
|
const char *data_ptr = (data == Qnil) ? NULL : RSTRING_PTR(data);
|
433
530
|
size_t data_len = (data == Qnil) ? -1 : RSTRING_LEN(data);
|
434
531
|
|
435
532
|
int rc;
|
436
533
|
switch (call_type) {
|
534
|
+
|
535
|
+
#ifdef THREADED
|
437
536
|
case SYNC:
|
438
537
|
rc = zkrb_call_zoo_set2(zk->zh, RSTRING_PTR(path), data_ptr, (int)data_len, FIX2INT(version), &stat);
|
439
538
|
break;
|
539
|
+
#endif
|
540
|
+
|
440
541
|
case ASYNC:
|
441
|
-
rc = zkrb_call_zoo_aset(
|
442
|
-
|
542
|
+
rc = zkrb_call_zoo_aset(
|
543
|
+
zk->zh, RSTRING_PTR(path), data_ptr, (int)data_len, FIX2INT(version), zkrb_stat_callback, CTX_ALLOC(zk, reqid));
|
443
544
|
break;
|
545
|
+
|
444
546
|
default:
|
445
|
-
|
446
|
-
return Qnil;
|
547
|
+
raise_invalid_call_type_err(call_type);
|
447
548
|
break;
|
448
549
|
}
|
449
550
|
|
450
|
-
|
551
|
+
output = rb_ary_new();
|
451
552
|
rb_ary_push(output, INT2FIX(rc));
|
452
553
|
if (IS_SYNC(call_type) && rc == ZOK) {
|
453
554
|
rb_ary_push(output, zkrb_stat_to_rarray(&stat));
|
@@ -456,21 +557,25 @@ static VALUE method_set(VALUE self, VALUE reqid, VALUE path, VALUE data, VALUE a
|
|
456
557
|
}
|
457
558
|
|
458
559
|
static VALUE method_set_acl(VALUE self, VALUE reqid, VALUE path, VALUE acls, VALUE async, VALUE version) {
|
459
|
-
|
460
|
-
|
560
|
+
STANDARD_PREAMBLE(self, zk, reqid, path, async, Qfalse, call_type);
|
561
|
+
|
461
562
|
struct ACL_vector * aclptr = zkrb_ruby_to_aclvector(acls);
|
462
563
|
|
463
564
|
int rc;
|
464
565
|
switch (call_type) {
|
566
|
+
|
567
|
+
#ifdef THREADED
|
465
568
|
case SYNC:
|
466
569
|
rc = zkrb_call_zoo_set_acl(zk->zh, RSTRING_PTR(path), FIX2INT(version), aclptr);
|
467
570
|
break;
|
571
|
+
#endif
|
572
|
+
|
468
573
|
case ASYNC:
|
469
|
-
rc = zkrb_call_zoo_aset_acl(zk->zh, RSTRING_PTR(path), FIX2INT(version), aclptr, zkrb_void_callback,
|
574
|
+
rc = zkrb_call_zoo_aset_acl(zk->zh, RSTRING_PTR(path), FIX2INT(version), aclptr, zkrb_void_callback, CTX_ALLOC(zk, reqid));
|
470
575
|
break;
|
576
|
+
|
471
577
|
default:
|
472
|
-
|
473
|
-
return Qnil;
|
578
|
+
raise_invalid_call_type_err(call_type);
|
474
579
|
break;
|
475
580
|
}
|
476
581
|
|
@@ -481,27 +586,31 @@ static VALUE method_set_acl(VALUE self, VALUE reqid, VALUE path, VALUE acls, VAL
|
|
481
586
|
}
|
482
587
|
|
483
588
|
static VALUE method_get_acl(VALUE self, VALUE reqid, VALUE path, VALUE async) {
|
484
|
-
|
485
|
-
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, data_ctx, watch_ctx, call_type);
|
589
|
+
STANDARD_PREAMBLE(self, zk, reqid, path, async, Qfalse, call_type);
|
486
590
|
|
591
|
+
VALUE output = Qnil;
|
487
592
|
struct ACL_vector acls;
|
488
593
|
struct Stat stat;
|
489
594
|
|
490
595
|
int rc;
|
491
596
|
switch (call_type) {
|
597
|
+
|
598
|
+
#ifdef THREADED
|
492
599
|
case SYNC:
|
493
600
|
rc = zkrb_call_zoo_get_acl(zk->zh, RSTRING_PTR(path), &acls, &stat);
|
494
601
|
break;
|
602
|
+
#endif
|
603
|
+
|
495
604
|
case ASYNC:
|
496
|
-
rc = zkrb_call_zoo_aget_acl(zk->zh, RSTRING_PTR(path), zkrb_acl_callback,
|
605
|
+
rc = zkrb_call_zoo_aget_acl(zk->zh, RSTRING_PTR(path), zkrb_acl_callback, CTX_ALLOC(zk, reqid));
|
497
606
|
break;
|
607
|
+
|
498
608
|
default:
|
499
|
-
|
500
|
-
return Qnil;
|
609
|
+
raise_invalid_call_type_err(call_type);
|
501
610
|
break;
|
502
611
|
}
|
503
612
|
|
504
|
-
|
613
|
+
output = rb_ary_new();
|
505
614
|
rb_ary_push(output, INT2FIX(rc));
|
506
615
|
if (IS_SYNC(call_type) && rc == ZOK) {
|
507
616
|
rb_ary_push(output, zkrb_acl_vector_to_ruby(&acls));
|
@@ -515,7 +624,7 @@ static VALUE method_get_acl(VALUE self, VALUE reqid, VALUE path, VALUE async) {
|
|
515
624
|
#define is_closed(self) RTEST(rb_iv_get(self, "@_closed"))
|
516
625
|
#define is_shutting_down(self) RTEST(rb_iv_get(self, "@_shutting_down"))
|
517
626
|
|
518
|
-
static VALUE
|
627
|
+
static VALUE method_zkrb_get_next_event(VALUE self, VALUE blocking) {
|
519
628
|
// dbg.h
|
520
629
|
check_debug(!is_closed(self), "we are closed, not trying to get event");
|
521
630
|
|
@@ -523,7 +632,7 @@ static VALUE method_get_next_event(VALUE self, VALUE blocking) {
|
|
523
632
|
FETCH_DATA_PTR(self, zk);
|
524
633
|
|
525
634
|
for (;;) {
|
526
|
-
check_debug(!is_closed(self), "we're closed in the middle of
|
635
|
+
check_debug(!is_closed(self), "we're closed in the middle of method_zkrb_get_next_event, bailing");
|
527
636
|
|
528
637
|
zkrb_event_t *event = zkrb_dequeue(zk->queue, 1);
|
529
638
|
|
@@ -534,7 +643,7 @@ static VALUE method_get_next_event(VALUE self, VALUE blocking) {
|
|
534
643
|
}
|
535
644
|
else {
|
536
645
|
// if we're shutting down, don't enter this section, we don't want to block
|
537
|
-
check_debug(!is_shutting_down(self), "
|
646
|
+
check_debug(!is_shutting_down(self), "method_zkrb_get_next_event, we're shutting down, don't enter blocking section");
|
538
647
|
|
539
648
|
int fd = zk->queue->pipe_read;
|
540
649
|
ssize_t bytes_read = 0;
|
@@ -565,6 +674,117 @@ static VALUE method_get_next_event(VALUE self, VALUE blocking) {
|
|
565
674
|
return Qnil;
|
566
675
|
}
|
567
676
|
|
677
|
+
// the single threaded version of this call. will go away when we do direct
|
678
|
+
// event delivery (soon)
|
679
|
+
static VALUE method_zkrb_get_next_event_st(VALUE self) {
|
680
|
+
VALUE rval = Qnil;
|
681
|
+
|
682
|
+
if (is_closed(self)) {
|
683
|
+
zkrb_debug("we are closed, not gonna try to get an event");
|
684
|
+
return Qnil;
|
685
|
+
}
|
686
|
+
|
687
|
+
FETCH_DATA_PTR(self, zk);
|
688
|
+
|
689
|
+
zkrb_event_t *event = zkrb_dequeue(zk->queue, 0);
|
690
|
+
|
691
|
+
if (event != NULL) {
|
692
|
+
rval = zkrb_event_to_ruby(event);
|
693
|
+
zkrb_event_free(event);
|
694
|
+
|
695
|
+
int fd = zk->queue->pipe_read;
|
696
|
+
|
697
|
+
// we don't care in this case. this is just until i can remove the self
|
698
|
+
// pipe from the queue
|
699
|
+
char b[128];
|
700
|
+
while(read(fd, b, sizeof(b)) == sizeof(b)){}
|
701
|
+
}
|
702
|
+
|
703
|
+
return rval;
|
704
|
+
}
|
705
|
+
|
706
|
+
inline static int get_self_pipe_read_fd(VALUE self) {
|
707
|
+
rb_io_t *fptr;
|
708
|
+
VALUE pipe_read = rb_iv_get(self, "@pipe_read");
|
709
|
+
|
710
|
+
if NIL_P(pipe_read)
|
711
|
+
rb_raise(rb_eRuntimeError, "@pipe_read was nil!");
|
712
|
+
|
713
|
+
GetOpenFile(pipe_read, fptr);
|
714
|
+
|
715
|
+
rb_io_check_readable(fptr);
|
716
|
+
|
717
|
+
#ifdef ZKRB_RUBY_187
|
718
|
+
return fileno(fptr->f);
|
719
|
+
#else
|
720
|
+
return fptr->fd;
|
721
|
+
#endif
|
722
|
+
}
|
723
|
+
|
724
|
+
|
725
|
+
static VALUE method_zkrb_iterate_event_loop(VALUE self) {
|
726
|
+
FETCH_DATA_PTR(self, zk);
|
727
|
+
|
728
|
+
fd_set rfds, wfds, efds;
|
729
|
+
FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
|
730
|
+
|
731
|
+
int fd=0, interest=0, events=0, rc=0, maxfd=0;
|
732
|
+
struct timeval tv;
|
733
|
+
|
734
|
+
zookeeper_interest(zk->zh, &fd, &interest, &tv);
|
735
|
+
|
736
|
+
if (fd != -1) {
|
737
|
+
if (interest & ZOOKEEPER_READ) {
|
738
|
+
FD_SET(fd, &rfds);
|
739
|
+
} else {
|
740
|
+
FD_CLR(fd, &rfds);
|
741
|
+
}
|
742
|
+
if (interest & ZOOKEEPER_WRITE) {
|
743
|
+
FD_SET(fd, &wfds);
|
744
|
+
} else {
|
745
|
+
FD_CLR(fd, &wfds);
|
746
|
+
}
|
747
|
+
} else {
|
748
|
+
fd = 0;
|
749
|
+
}
|
750
|
+
|
751
|
+
// add our self-pipe to the read set, allow us to wake up in case our attention is needed
|
752
|
+
int pipe_r_fd = get_self_pipe_read_fd(self);
|
753
|
+
|
754
|
+
FD_SET(pipe_r_fd, &rfds);
|
755
|
+
|
756
|
+
maxfd = (pipe_r_fd > fd) ? pipe_r_fd : fd;
|
757
|
+
|
758
|
+
rc = rb_thread_select(maxfd+1, &rfds, &wfds, &efds, &tv);
|
759
|
+
|
760
|
+
if (rc > 0) {
|
761
|
+
if (FD_ISSET(fd, &rfds)) {
|
762
|
+
events |= ZOOKEEPER_READ;
|
763
|
+
}
|
764
|
+
if (FD_ISSET(fd, &wfds)) {
|
765
|
+
events |= ZOOKEEPER_WRITE;
|
766
|
+
}
|
767
|
+
|
768
|
+
// we got woken up by the self-pipe
|
769
|
+
if (FD_ISSET(pipe_r_fd, &rfds)) {
|
770
|
+
// flush the pipe (from mt_adaptor.c)
|
771
|
+
char b[1];
|
772
|
+
read(pipe_r_fd, b, 1); // one event has awoken us, so we clear one event from the pipe
|
773
|
+
}
|
774
|
+
|
775
|
+
rc = zookeeper_process(zk->zh, events);
|
776
|
+
}
|
777
|
+
else if (rc == 0) {
|
778
|
+
zkrb_debug("timed out waiting for descriptor to be ready");
|
779
|
+
}
|
780
|
+
else {
|
781
|
+
log_err("select returned: %d", rc);
|
782
|
+
}
|
783
|
+
|
784
|
+
return INT2FIX(rc);
|
785
|
+
}
|
786
|
+
|
787
|
+
|
568
788
|
static VALUE method_has_events(VALUE self) {
|
569
789
|
VALUE rb_event;
|
570
790
|
FETCH_DATA_PTR(self, zk);
|
@@ -575,6 +795,7 @@ static VALUE method_has_events(VALUE self) {
|
|
575
795
|
|
576
796
|
|
577
797
|
// wake up the event loop, used when shutting down
|
798
|
+
#if 0
|
578
799
|
static VALUE method_wake_event_loop_bang(VALUE self) {
|
579
800
|
FETCH_DATA_PTR(self, zk);
|
580
801
|
|
@@ -583,12 +804,12 @@ static VALUE method_wake_event_loop_bang(VALUE self) {
|
|
583
804
|
|
584
805
|
return Qnil;
|
585
806
|
};
|
807
|
+
#endif
|
586
808
|
|
587
809
|
static VALUE method_close_handle(VALUE self) {
|
588
810
|
FETCH_DATA_PTR(self, zk);
|
589
811
|
|
590
812
|
if (ZKRBDebugging) {
|
591
|
-
/* fprintf(stderr, "CLOSING ZK INSTANCE: obj_id %lx", FIX2LONG(rb_obj_id(self)));*/
|
592
813
|
zkrb_debug_inst(self, "CLOSING_ZK_INSTANCE");
|
593
814
|
print_zkrb_instance_data(zk);
|
594
815
|
}
|
@@ -597,15 +818,12 @@ static VALUE method_close_handle(VALUE self) {
|
|
597
818
|
// has been called
|
598
819
|
rb_iv_set(self, "@_closed", Qtrue);
|
599
820
|
|
600
|
-
zkrb_debug_inst(self, "calling destroy_zkrb_instance");
|
601
|
-
|
602
821
|
/* Note that after zookeeper_close() returns, ZK handle is invalid */
|
603
822
|
int rc = destroy_zkrb_instance(zk);
|
604
823
|
|
605
824
|
zkrb_debug("destroy_zkrb_instance returned: %d", rc);
|
606
825
|
|
607
|
-
return
|
608
|
-
/* return INT2FIX(rc);*/
|
826
|
+
return INT2FIX(rc);
|
609
827
|
}
|
610
828
|
|
611
829
|
static VALUE method_deterministic_conn_order(VALUE self, VALUE yn) {
|
@@ -634,12 +852,19 @@ static VALUE method_recv_timeout(VALUE self) {
|
|
634
852
|
/* return UINT2NUM(id->client_id);*/
|
635
853
|
/*}*/
|
636
854
|
|
637
|
-
|
638
855
|
// returns a CZookeeper::ClientId object with the values set for session_id and passwd
|
639
856
|
static VALUE method_client_id(VALUE self) {
|
640
857
|
FETCH_DATA_PTR(self, zk);
|
858
|
+
char buf[32];
|
641
859
|
const clientid_t *cid = zoo_client_id(zk->zh);
|
642
860
|
|
861
|
+
if (strlen(cid->passwd) != 16) {
|
862
|
+
zkrb_debug("passwd is not null-termniated");
|
863
|
+
} else {
|
864
|
+
hexbufify(buf, cid->passwd, 16);
|
865
|
+
zkrb_debug("password in hex is: %s", buf);
|
866
|
+
}
|
867
|
+
|
643
868
|
VALUE session_id = LL2NUM(cid->client_id);
|
644
869
|
VALUE passwd = rb_str_new2(cid->passwd);
|
645
870
|
|
@@ -663,21 +888,28 @@ static VALUE method_zerror(VALUE self, VALUE errc) {
|
|
663
888
|
}
|
664
889
|
|
665
890
|
static void zkrb_define_methods(void) {
|
666
|
-
#define DEFINE_METHOD(
|
667
|
-
rb_define_method(CZookeeper, #
|
668
|
-
|
669
|
-
|
891
|
+
#define DEFINE_METHOD(M, ARGS) { \
|
892
|
+
rb_define_method(CZookeeper, #M, method_ ## M, ARGS); }
|
893
|
+
|
894
|
+
#define DEFINE_CLASS_METHOD(M, ARGS) { \
|
895
|
+
rb_define_singleton_method(CZookeeper, #M, method_ ## M, ARGS); }
|
896
|
+
|
897
|
+
// defines a method with a zkrb_ prefix, the actual C method does not have this prefix
|
898
|
+
#define DEFINE_ZKRB_METHOD(M, ARGS) { \
|
899
|
+
rb_define_method(CZookeeper, zkrb_ ## M, method_ ## M, ARGS); }
|
670
900
|
|
671
901
|
// the number after the method name should be actual arity of C function - 1
|
672
902
|
DEFINE_METHOD(zkrb_init, -1);
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
903
|
+
|
904
|
+
rb_define_method(CZookeeper, "zkrb_get_children", method_get_children, 4);
|
905
|
+
rb_define_method(CZookeeper, "zkrb_exists", method_exists, 4);
|
906
|
+
rb_define_method(CZookeeper, "zkrb_create", method_create, 6);
|
907
|
+
rb_define_method(CZookeeper, "zkrb_delete", method_delete, 4);
|
908
|
+
rb_define_method(CZookeeper, "zkrb_get", method_get, 4);
|
909
|
+
rb_define_method(CZookeeper, "zkrb_set", method_set, 5);
|
910
|
+
rb_define_method(CZookeeper, "zkrb_set_acl", method_set_acl, 5);
|
911
|
+
rb_define_method(CZookeeper, "zkrb_get_acl", method_get_acl, 3);
|
912
|
+
|
681
913
|
DEFINE_METHOD(client_id, 0);
|
682
914
|
DEFINE_METHOD(close_handle, 0);
|
683
915
|
DEFINE_METHOD(deterministic_conn_order, 1);
|
@@ -685,12 +917,15 @@ static void zkrb_define_methods(void) {
|
|
685
917
|
DEFINE_METHOD(recv_timeout, 1);
|
686
918
|
DEFINE_METHOD(zkrb_state, 0);
|
687
919
|
DEFINE_METHOD(sync, 2);
|
920
|
+
DEFINE_METHOD(zkrb_iterate_event_loop, 0);
|
921
|
+
DEFINE_METHOD(zkrb_get_next_event_st, 0);
|
688
922
|
|
689
923
|
// TODO
|
690
924
|
// DEFINE_METHOD(add_auth, 3);
|
691
925
|
|
692
926
|
// methods for the ruby-side event manager
|
693
|
-
DEFINE_METHOD(
|
927
|
+
DEFINE_METHOD(zkrb_get_next_event, 1);
|
928
|
+
DEFINE_METHOD(zkrb_get_next_event_st, 0);
|
694
929
|
DEFINE_METHOD(has_events, 0);
|
695
930
|
|
696
931
|
// Make these class methods?
|
@@ -699,7 +934,6 @@ static void zkrb_define_methods(void) {
|
|
699
934
|
rb_define_singleton_method(CZookeeper, "set_zkrb_debug_level", klass_method_zkrb_set_debug_level, 1);
|
700
935
|
|
701
936
|
rb_attr(CZookeeper, rb_intern("selectable_io"), 1, 0, Qtrue);
|
702
|
-
rb_define_method(CZookeeper, "wake_event_loop!", method_wake_event_loop_bang, 0);
|
703
937
|
|
704
938
|
}
|
705
939
|
|
@@ -723,6 +957,10 @@ void Init_zookeeper_c() {
|
|
723
957
|
ZKRBDebugging = 0;
|
724
958
|
|
725
959
|
mZookeeper = rb_define_module("Zookeeper");
|
960
|
+
mZookeeperExceptions = rb_define_module_under(mZookeeper, "Exceptions");
|
961
|
+
|
962
|
+
// this will likely fail if the load order is screwed up
|
963
|
+
eHandleClosedException = rb_const_get(mZookeeperExceptions, rb_intern("HandleClosedException"));
|
726
964
|
|
727
965
|
/* initialize CZookeeper class */
|
728
966
|
CZookeeper = rb_define_class_under(mZookeeper, "CZookeeper", rb_cObject);
|
@@ -732,6 +970,7 @@ void Init_zookeeper_c() {
|
|
732
970
|
rb_define_method(ZookeeperClientId, "initialize", zkrb_client_id_method_initialize, 0);
|
733
971
|
rb_define_attr(ZookeeperClientId, "session_id", 1, 1);
|
734
972
|
rb_define_attr(ZookeeperClientId, "passwd", 1, 1);
|
973
|
+
|
735
974
|
}
|
736
975
|
|
737
976
|
// vim:ts=2:sw=2:sts=2:et
|