zookeeper 0.4.4 → 0.9.3
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/.gitignore +10 -0
- data/CHANGELOG +95 -0
- data/Gemfile +17 -0
- data/Manifest +8 -2
- data/README.markdown +59 -0
- data/Rakefile +137 -7
- data/ext/.gitignore +6 -0
- data/ext/Rakefile +51 -0
- data/ext/c_zookeeper.rb +212 -0
- data/ext/dbg.h +53 -0
- data/ext/depend +5 -0
- data/ext/extconf.rb +44 -15
- data/ext/generate_gvl_code.rb +316 -0
- data/ext/zkc-3.3.5.tar.gz +0 -0
- data/ext/zkrb_wrapper.c +731 -0
- data/ext/zkrb_wrapper.h +330 -0
- data/ext/zkrb_wrapper_compat.c +15 -0
- data/ext/zkrb_wrapper_compat.h +11 -0
- data/ext/zookeeper_base.rb +211 -0
- data/ext/zookeeper_c.c +268 -97
- data/ext/zookeeper_lib.c +157 -92
- data/ext/zookeeper_lib.h +12 -6
- data/java/zookeeper_base.rb +477 -0
- data/lib/zookeeper/acls.rb +10 -1
- data/lib/zookeeper/callbacks.rb +5 -3
- data/lib/zookeeper/common/queue_with_pipe.rb +78 -0
- data/lib/zookeeper/common.rb +174 -0
- data/lib/zookeeper/constants.rb +31 -28
- data/lib/zookeeper/em_client.rb +55 -0
- data/lib/zookeeper/exceptions.rb +10 -2
- data/lib/zookeeper/stat.rb +11 -2
- data/lib/zookeeper/version.rb +6 -0
- data/lib/zookeeper.rb +155 -122
- data/notes.txt +14 -0
- data/spec/c_zookeeper_spec.rb +50 -0
- data/spec/chrooted_connection_spec.rb +81 -0
- data/spec/default_watcher_spec.rb +41 -0
- data/spec/em_spec.rb +51 -0
- data/spec/log4j.properties +17 -0
- data/spec/shared/all_success_return_values.rb +10 -0
- data/spec/shared/connection_examples.rb +1018 -0
- data/spec/spec_helper.rb +119 -0
- data/spec/support/progress_formatter.rb +15 -0
- data/spec/zookeeper_spec.rb +24 -0
- data/zookeeper.gemspec +37 -25
- metadata +78 -34
- data/README +0 -42
- data/ext/zkc-3.3.2.tar.gz +0 -0
data/ext/zookeeper_c.c
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
* Phillip Pearson <pp@myelin.co.nz>
|
3
3
|
* Eric Maland <eric@twitter.com>
|
4
4
|
* Brian Wickman <wickman@twitter.com>
|
5
|
+
* Jonathan D. Simms <slyphon@gmail.com>
|
5
6
|
*
|
6
7
|
* This fork is a 90% rewrite of the original. It takes a more evented
|
7
8
|
* approach to isolate the ZK state machine from the ruby interpreter via an
|
@@ -17,16 +18,24 @@
|
|
17
18
|
#include <stdio.h>
|
18
19
|
#include <stdlib.h>
|
19
20
|
#include <unistd.h>
|
21
|
+
#include <sys/fcntl.h>
|
22
|
+
#include <pthread.h>
|
23
|
+
#include <inttypes.h>
|
20
24
|
|
21
25
|
#include "zookeeper_lib.h"
|
26
|
+
#include "zkrb_wrapper.h"
|
27
|
+
#include "dbg.h"
|
22
28
|
|
23
29
|
static VALUE Zookeeper = Qnil;
|
30
|
+
static VALUE ZookeeperClientId = Qnil;
|
31
|
+
|
32
|
+
// slyphon: possibly add a lock to this for synchronizing during get_next_event
|
24
33
|
|
25
34
|
struct zkrb_instance_data {
|
26
35
|
zhandle_t *zh;
|
27
36
|
clientid_t myid;
|
28
37
|
zkrb_queue_t *queue;
|
29
|
-
|
38
|
+
long object_id; // the ruby object this instance data is associated with
|
30
39
|
};
|
31
40
|
|
32
41
|
typedef enum {
|
@@ -39,21 +48,28 @@ typedef enum {
|
|
39
48
|
#define IS_SYNC(zkrbcall) ((zkrbcall)==SYNC || (zkrbcall)==SYNC_WATCH)
|
40
49
|
#define IS_ASYNC(zkrbcall) ((zkrbcall)==ASYNC || (zkrbcall)==ASYNC_WATCH)
|
41
50
|
|
51
|
+
|
42
52
|
static int destroy_zkrb_instance(struct zkrb_instance_data* ptr) {
|
43
53
|
int rv = ZOK;
|
44
54
|
|
45
55
|
if (ptr->zh) {
|
46
56
|
const void *ctx = zoo_get_context(ptr->zh);
|
47
57
|
/* Note that after zookeeper_close() returns, ZK handle is invalid */
|
58
|
+
zkrb_debug("obj_id: %lx, calling zookeeper_close", ptr->object_id);
|
48
59
|
rv = zookeeper_close(ptr->zh);
|
60
|
+
zkrb_debug("obj_id: %lx, zookeeper_close returned %d", ptr->object_id, rv);
|
49
61
|
free((void *) ctx);
|
50
62
|
}
|
51
63
|
|
52
64
|
#warning [wickman] TODO: fire off warning if queue is not empty
|
53
|
-
if (ptr->queue)
|
65
|
+
if (ptr->queue) {
|
66
|
+
zkrb_debug("obj_id: %lx, freeing queue pointer: %p", ptr->object_id, ptr->queue);
|
67
|
+
zkrb_queue_free(ptr->queue);
|
68
|
+
}
|
54
69
|
|
55
70
|
ptr->zh = NULL;
|
56
71
|
ptr->queue = NULL;
|
72
|
+
|
57
73
|
return rv;
|
58
74
|
}
|
59
75
|
|
@@ -63,16 +79,65 @@ static void free_zkrb_instance_data(struct zkrb_instance_data* ptr) {
|
|
63
79
|
|
64
80
|
static void print_zkrb_instance_data(struct zkrb_instance_data* ptr) {
|
65
81
|
fprintf(stderr, "zkrb_instance_data (%p) {\n", ptr);
|
66
|
-
fprintf(stderr, "
|
67
|
-
fprintf(stderr, "
|
68
|
-
fprintf(stderr, "
|
69
|
-
fprintf(stderr, "
|
82
|
+
fprintf(stderr, " zh = %p\n", ptr->zh);
|
83
|
+
fprintf(stderr, " { state = %d }\n", zoo_state(ptr->zh));
|
84
|
+
fprintf(stderr, " id = %"PRId64"\n", ptr->myid.client_id); // PRId64 defined in inttypes.h
|
85
|
+
fprintf(stderr, " q = %p\n", ptr->queue);
|
86
|
+
fprintf(stderr, " obj_id = %lx\n", ptr->object_id);
|
70
87
|
fprintf(stderr, "}\n");
|
71
88
|
}
|
72
89
|
|
73
|
-
|
90
|
+
// cargo culted from io.c
|
91
|
+
static VALUE zkrb_new_instance _((VALUE));
|
92
|
+
|
93
|
+
static VALUE zkrb_new_instance(VALUE args) {
|
94
|
+
return rb_class_new_instance(2, (VALUE*)args+1, *(VALUE*)args);
|
95
|
+
}
|
96
|
+
|
97
|
+
static int zkrb_dup(int orig) {
|
98
|
+
int fd;
|
99
|
+
|
100
|
+
fd = dup(orig);
|
101
|
+
if (fd < 0) {
|
102
|
+
if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {
|
103
|
+
rb_gc();
|
104
|
+
fd = dup(orig);
|
105
|
+
}
|
106
|
+
if (fd < 0) {
|
107
|
+
rb_sys_fail(0);
|
108
|
+
}
|
109
|
+
}
|
110
|
+
return fd;
|
111
|
+
}
|
112
|
+
|
113
|
+
#if 0
|
114
|
+
static VALUE create_selectable_io(zkrb_queue_t *q) {
|
115
|
+
// rb_cIO is the ruby IO class?
|
116
|
+
|
117
|
+
int pipe, state, read_fd;
|
118
|
+
VALUE args[3], reader;
|
119
|
+
|
120
|
+
read_fd = zkrb_dup(q->pipe_read);
|
121
|
+
|
122
|
+
args[0] = rb_cIO;
|
123
|
+
args[1] = INT2NUM(read_fd);
|
124
|
+
args[2] = INT2FIX(O_RDONLY);
|
125
|
+
reader = rb_protect(zkrb_new_instance, (VALUE)args, &state);
|
126
|
+
|
127
|
+
if (state) {
|
128
|
+
rb_jump_tag(state);
|
129
|
+
}
|
130
|
+
|
131
|
+
return reader;
|
132
|
+
}
|
133
|
+
#endif
|
134
|
+
|
135
|
+
#define session_timeout_msec(self) rb_iv_get(self, "@_session_timeout_msec")
|
136
|
+
|
137
|
+
static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
|
74
138
|
VALUE hostPort;
|
75
139
|
VALUE options;
|
140
|
+
|
76
141
|
rb_scan_args(argc, argv, "11", &hostPort, &options);
|
77
142
|
|
78
143
|
if (NIL_P(options)) {
|
@@ -89,29 +154,30 @@ static VALUE method_init(int argc, VALUE* argv, VALUE self) {
|
|
89
154
|
zoo_set_debug_level(0); // no log messages
|
90
155
|
} else {
|
91
156
|
Check_Type(log_level, T_FIXNUM);
|
92
|
-
zoo_set_debug_level(log_level);
|
157
|
+
zoo_set_debug_level((int)log_level);
|
93
158
|
}
|
94
159
|
|
160
|
+
|
95
161
|
VALUE data;
|
96
162
|
struct zkrb_instance_data *zk_local_ctx;
|
97
|
-
data = Data_Make_Struct(Zookeeper,
|
98
|
-
struct zkrb_instance_data,
|
99
|
-
0,
|
100
|
-
free_zkrb_instance_data,
|
101
|
-
zk_local_ctx);
|
163
|
+
data = Data_Make_Struct(Zookeeper, struct zkrb_instance_data, 0, free_zkrb_instance_data, zk_local_ctx);
|
102
164
|
zk_local_ctx->queue = zkrb_queue_alloc();
|
103
|
-
|
165
|
+
|
166
|
+
if (zk_local_ctx->queue == NULL)
|
167
|
+
rb_raise(rb_eRuntimeError, "could not allocate zkrb queue!");
|
104
168
|
|
105
169
|
zoo_deterministic_conn_order(0);
|
106
170
|
|
107
171
|
zkrb_calling_context *ctx =
|
108
172
|
zkrb_calling_context_alloc(ZKRB_GLOBAL_REQ, zk_local_ctx->queue);
|
109
173
|
|
174
|
+
zk_local_ctx->object_id = FIX2LONG(rb_obj_id(self));
|
175
|
+
|
110
176
|
zk_local_ctx->zh =
|
111
177
|
zookeeper_init(
|
112
178
|
RSTRING_PTR(hostPort),
|
113
179
|
zkrb_state_callback,
|
114
|
-
|
180
|
+
session_timeout_msec(self),
|
115
181
|
&zk_local_ctx->myid,
|
116
182
|
ctx,
|
117
183
|
0);
|
@@ -121,40 +187,42 @@ static VALUE method_init(int argc, VALUE* argv, VALUE self) {
|
|
121
187
|
rb_raise(rb_eRuntimeError, "error connecting to zookeeper: %d", errno);
|
122
188
|
}
|
123
189
|
|
124
|
-
rb_iv_set(self, "@
|
190
|
+
rb_iv_set(self, "@_data", data);
|
191
|
+
rb_funcall(self, rb_intern("zkc_set_running_and_notify!"), 0);
|
125
192
|
|
193
|
+
error:
|
126
194
|
return Qnil;
|
127
195
|
}
|
128
196
|
|
129
|
-
#define FETCH_DATA_PTR(
|
130
|
-
struct zkrb_instance_data *
|
131
|
-
Data_Get_Struct(rb_iv_get(
|
132
|
-
if ((
|
197
|
+
#define FETCH_DATA_PTR(X, Y) \
|
198
|
+
struct zkrb_instance_data * Y; \
|
199
|
+
Data_Get_Struct(rb_iv_get(X, "@_data"), struct zkrb_instance_data, Y); \
|
200
|
+
if ((Y)->zh == NULL) \
|
133
201
|
rb_raise(rb_eRuntimeError, "zookeeper handle is closed")
|
134
202
|
|
135
203
|
#define STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, cb_ctx, w_ctx, call_type) \
|
136
|
-
if (TYPE(reqid) != T_FIXNUM && TYPE(reqid) != T_BIGNUM) {
|
137
|
-
rb_raise(rb_eTypeError, "reqid must be Fixnum/Bignum");
|
138
|
-
return Qnil;
|
139
|
-
}
|
140
|
-
Check_Type(path, T_STRING);
|
141
|
-
struct zkrb_instance_data * zk;
|
142
|
-
Data_Get_Struct(rb_iv_get(self, "@
|
143
|
-
if (!zk->zh)
|
144
|
-
rb_raise(rb_eRuntimeError, "zookeeper handle is closed");
|
145
|
-
zkrb_calling_context* cb_ctx =
|
146
|
-
(async != Qfalse && async != Qnil) ?
|
147
|
-
zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) :
|
148
|
-
NULL;
|
149
|
-
zkrb_calling_context* w_ctx =
|
150
|
-
(watch != Qfalse && watch != Qnil) ?
|
151
|
-
zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) :
|
152
|
-
NULL;
|
153
|
-
int
|
154
|
-
int
|
155
|
-
zkrb_call_type call_type;
|
156
|
-
if (
|
157
|
-
|
204
|
+
if (TYPE(reqid) != T_FIXNUM && TYPE(reqid) != T_BIGNUM) { \
|
205
|
+
rb_raise(rb_eTypeError, "reqid must be Fixnum/Bignum"); \
|
206
|
+
return Qnil; \
|
207
|
+
} \
|
208
|
+
Check_Type(path, T_STRING); \
|
209
|
+
struct zkrb_instance_data * zk; \
|
210
|
+
Data_Get_Struct(rb_iv_get(self, "@_data"), struct zkrb_instance_data, zk); \
|
211
|
+
if (!zk->zh) \
|
212
|
+
rb_raise(rb_eRuntimeError, "zookeeper handle is closed"); \
|
213
|
+
zkrb_calling_context* cb_ctx = \
|
214
|
+
(async != Qfalse && async != Qnil) ? \
|
215
|
+
zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) : \
|
216
|
+
NULL; \
|
217
|
+
zkrb_calling_context* w_ctx = \
|
218
|
+
(watch != Qfalse && watch != Qnil) ? \
|
219
|
+
zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) : \
|
220
|
+
NULL; \
|
221
|
+
int a_ = (async != Qfalse && async != Qnil); \
|
222
|
+
int w_ = (watch != Qfalse && watch != Qnil); \
|
223
|
+
zkrb_call_type call_type; \
|
224
|
+
if (a_) { if (w_) { call_type = ASYNC_WATCH; } else { call_type = ASYNC; } } \
|
225
|
+
else { if (w_) { call_type = SYNC_WATCH; } else { call_type = SYNC; } }
|
158
226
|
|
159
227
|
static VALUE method_get_children(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE watch) {
|
160
228
|
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, data_ctx, watch_ctx, call_type);
|
@@ -165,19 +233,19 @@ static VALUE method_get_children(VALUE self, VALUE reqid, VALUE path, VALUE asyn
|
|
165
233
|
int rc;
|
166
234
|
switch (call_type) {
|
167
235
|
case SYNC:
|
168
|
-
rc =
|
236
|
+
rc = zkrb_call_zoo_get_children2(zk->zh, RSTRING_PTR(path), 0, &strings, &stat);
|
169
237
|
break;
|
170
238
|
|
171
239
|
case SYNC_WATCH:
|
172
|
-
rc =
|
240
|
+
rc = zkrb_call_zoo_wget_children2(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, &strings, &stat);
|
173
241
|
break;
|
174
242
|
|
175
243
|
case ASYNC:
|
176
|
-
rc =
|
244
|
+
rc = zkrb_call_zoo_aget_children2(zk->zh, RSTRING_PTR(path), 0, zkrb_strings_stat_callback, data_ctx);
|
177
245
|
break;
|
178
246
|
|
179
247
|
case ASYNC_WATCH:
|
180
|
-
rc =
|
248
|
+
rc = zkrb_call_zoo_awget_children2(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, zkrb_strings_stat_callback, data_ctx);
|
181
249
|
break;
|
182
250
|
}
|
183
251
|
|
@@ -198,19 +266,19 @@ static VALUE method_exists(VALUE self, VALUE reqid, VALUE path, VALUE async, VAL
|
|
198
266
|
int rc;
|
199
267
|
switch (call_type) {
|
200
268
|
case SYNC:
|
201
|
-
rc =
|
269
|
+
rc = zkrb_call_zoo_exists(zk->zh, RSTRING_PTR(path), 0, &stat);
|
202
270
|
break;
|
203
271
|
|
204
272
|
case SYNC_WATCH:
|
205
|
-
rc =
|
273
|
+
rc = zkrb_call_zoo_wexists(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, &stat);
|
206
274
|
break;
|
207
275
|
|
208
276
|
case ASYNC:
|
209
|
-
rc =
|
277
|
+
rc = zkrb_call_zoo_aexists(zk->zh, RSTRING_PTR(path), 0, zkrb_stat_callback, data_ctx);
|
210
278
|
break;
|
211
279
|
|
212
280
|
case ASYNC_WATCH:
|
213
|
-
rc =
|
281
|
+
rc = zkrb_call_zoo_awexists(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, zkrb_stat_callback, data_ctx);
|
214
282
|
break;
|
215
283
|
}
|
216
284
|
|
@@ -222,6 +290,19 @@ static VALUE method_exists(VALUE self, VALUE reqid, VALUE path, VALUE async, VAL
|
|
222
290
|
return output;
|
223
291
|
}
|
224
292
|
|
293
|
+
// this method is *only* called asynchronously
|
294
|
+
static VALUE method_sync(VALUE self, VALUE reqid, VALUE path) {
|
295
|
+
VALUE async = Qtrue;
|
296
|
+
VALUE watch = Qfalse;
|
297
|
+
int rc;
|
298
|
+
|
299
|
+
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, data_ctx, watch_ctx, call_type);
|
300
|
+
|
301
|
+
rc = zkrb_call_zoo_async(zk->zh, RSTRING_PTR(path), zkrb_string_callback, data_ctx);
|
302
|
+
|
303
|
+
return INT2FIX(rc);
|
304
|
+
}
|
305
|
+
|
225
306
|
static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALUE async, VALUE acls, VALUE flags) {
|
226
307
|
VALUE watch = Qfalse;
|
227
308
|
STANDARD_PREAMBLE(self, zk, reqid, path, async, watch, data_ctx, watch_ctx, call_type);
|
@@ -238,10 +319,13 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
|
|
238
319
|
int rc;
|
239
320
|
switch (call_type) {
|
240
321
|
case SYNC:
|
241
|
-
|
322
|
+
// casting data_len to int is OK as you can only store 1MB in zookeeper
|
323
|
+
rc = zkrb_call_zoo_create(zk->zh, RSTRING_PTR(path), data_ptr, (int)data_len, aclptr, FIX2INT(flags), realpath, sizeof(realpath));
|
324
|
+
|
242
325
|
break;
|
243
326
|
case ASYNC:
|
244
|
-
rc =
|
327
|
+
rc = zkrb_call_zoo_acreate(zk->zh, RSTRING_PTR(path), data_ptr, (int)data_len, aclptr, FIX2INT(flags), zkrb_string_callback, data_ctx);
|
328
|
+
|
245
329
|
break;
|
246
330
|
default:
|
247
331
|
/* TODO(wickman) raise proper argument error */
|
@@ -249,6 +333,7 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
|
|
249
333
|
break;
|
250
334
|
}
|
251
335
|
|
336
|
+
|
252
337
|
if (aclptr) {
|
253
338
|
deallocate_ACL_vector(aclptr);
|
254
339
|
free(aclptr);
|
@@ -270,10 +355,10 @@ static VALUE method_delete(VALUE self, VALUE reqid, VALUE path, VALUE version, V
|
|
270
355
|
int rc = 0;
|
271
356
|
switch (call_type) {
|
272
357
|
case SYNC:
|
273
|
-
rc =
|
358
|
+
rc = zkrb_call_zoo_delete(zk->zh, RSTRING_PTR(path), FIX2INT(version));
|
274
359
|
break;
|
275
360
|
case ASYNC:
|
276
|
-
rc =
|
361
|
+
rc = zkrb_call_zoo_adelete(zk->zh, RSTRING_PTR(path), FIX2INT(version), zkrb_void_callback, data_ctx);
|
277
362
|
break;
|
278
363
|
default:
|
279
364
|
/* TODO(wickman) raise proper argument error */
|
@@ -298,19 +383,19 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
|
|
298
383
|
|
299
384
|
switch (call_type) {
|
300
385
|
case SYNC:
|
301
|
-
rc =
|
386
|
+
rc = zkrb_call_zoo_get(zk->zh, RSTRING_PTR(path), 0, data, &data_len, &stat);
|
302
387
|
break;
|
303
388
|
|
304
389
|
case SYNC_WATCH:
|
305
|
-
rc =
|
390
|
+
rc = zkrb_call_zoo_wget(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, data, &data_len, &stat);
|
306
391
|
break;
|
307
392
|
|
308
393
|
case ASYNC:
|
309
|
-
rc =
|
394
|
+
rc = zkrb_call_zoo_aget(zk->zh, RSTRING_PTR(path), 0, zkrb_data_callback, data_ctx);
|
310
395
|
break;
|
311
396
|
|
312
397
|
case ASYNC_WATCH:
|
313
|
-
rc =
|
398
|
+
rc = zkrb_call_zoo_awget(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, zkrb_data_callback, data_ctx);
|
314
399
|
break;
|
315
400
|
}
|
316
401
|
|
@@ -340,10 +425,10 @@ static VALUE method_set(VALUE self, VALUE reqid, VALUE path, VALUE data, VALUE a
|
|
340
425
|
int rc;
|
341
426
|
switch (call_type) {
|
342
427
|
case SYNC:
|
343
|
-
rc =
|
428
|
+
rc = zkrb_call_zoo_set2(zk->zh, RSTRING_PTR(path), data_ptr, (int)data_len, FIX2INT(version), &stat);
|
344
429
|
break;
|
345
430
|
case ASYNC:
|
346
|
-
rc =
|
431
|
+
rc = zkrb_call_zoo_aset(zk->zh, RSTRING_PTR(path), data_ptr, (int)data_len, FIX2INT(version),
|
347
432
|
zkrb_stat_callback, data_ctx);
|
348
433
|
break;
|
349
434
|
default:
|
@@ -368,10 +453,10 @@ static VALUE method_set_acl(VALUE self, VALUE reqid, VALUE path, VALUE acls, VAL
|
|
368
453
|
int rc;
|
369
454
|
switch (call_type) {
|
370
455
|
case SYNC:
|
371
|
-
rc =
|
456
|
+
rc = zkrb_call_zoo_set_acl(zk->zh, RSTRING_PTR(path), FIX2INT(version), aclptr);
|
372
457
|
break;
|
373
458
|
case ASYNC:
|
374
|
-
rc =
|
459
|
+
rc = zkrb_call_zoo_aset_acl(zk->zh, RSTRING_PTR(path), FIX2INT(version), aclptr, zkrb_void_callback, data_ctx);
|
375
460
|
break;
|
376
461
|
default:
|
377
462
|
/* TODO(wickman) raise proper argument error */
|
@@ -395,10 +480,10 @@ static VALUE method_get_acl(VALUE self, VALUE reqid, VALUE path, VALUE async) {
|
|
395
480
|
int rc;
|
396
481
|
switch (call_type) {
|
397
482
|
case SYNC:
|
398
|
-
rc =
|
483
|
+
rc = zkrb_call_zoo_get_acl(zk->zh, RSTRING_PTR(path), &acls, &stat);
|
399
484
|
break;
|
400
485
|
case ASYNC:
|
401
|
-
rc =
|
486
|
+
rc = zkrb_call_zoo_aget_acl(zk->zh, RSTRING_PTR(path), zkrb_acl_callback, data_ctx);
|
402
487
|
break;
|
403
488
|
default:
|
404
489
|
/* TODO(wickman) raise proper argument error */
|
@@ -416,37 +501,58 @@ static VALUE method_get_acl(VALUE self, VALUE reqid, VALUE path, VALUE async) {
|
|
416
501
|
return output;
|
417
502
|
}
|
418
503
|
|
419
|
-
|
504
|
+
#define is_running(self) RTEST(rb_iv_get(self, "@_running"))
|
505
|
+
#define is_closed(self) RTEST(rb_iv_get(self, "@_closed"))
|
506
|
+
#define is_shutting_down(self) RTEST(rb_iv_get(self, "@_shutting_down"))
|
507
|
+
|
508
|
+
static VALUE method_get_next_event(VALUE self, VALUE blocking) {
|
509
|
+
// dbg.h
|
510
|
+
check_debug(!is_closed(self), "we are closed, not trying to get event");
|
511
|
+
|
420
512
|
char buf[64];
|
421
513
|
FETCH_DATA_PTR(self, zk);
|
422
514
|
|
423
515
|
for (;;) {
|
516
|
+
check_debug(!is_closed(self), "we're closed in the middle of method_get_next_event, bailing");
|
517
|
+
|
424
518
|
zkrb_event_t *event = zkrb_dequeue(zk->queue, 1);
|
425
519
|
|
426
520
|
/* Wait for an event using rb_thread_select() on the queue's pipe */
|
427
521
|
if (event == NULL) {
|
428
|
-
|
429
|
-
|
522
|
+
if (NIL_P(blocking) || (blocking == Qfalse)) {
|
523
|
+
goto error;
|
524
|
+
}
|
525
|
+
else {
|
526
|
+
// if we're shutting down, don't enter this section, we don't want to block
|
527
|
+
check_debug(!is_shutting_down(self), "method_get_next_event, we're shutting down, don't enter blocking section");
|
430
528
|
|
431
|
-
|
432
|
-
|
529
|
+
int fd = zk->queue->pipe_read;
|
530
|
+
ssize_t bytes_read = 0;
|
433
531
|
|
434
|
-
|
435
|
-
|
532
|
+
// wait for an fd to become readable, opposite of rb_thread_fd_writable
|
533
|
+
rb_thread_wait_fd(fd);
|
436
534
|
|
437
|
-
|
438
|
-
|
535
|
+
// clear all bytes here, we'll catch all the events on subsequent calls
|
536
|
+
// (until we run out of events)
|
537
|
+
bytes_read = read(fd, buf, sizeof(buf));
|
439
538
|
|
440
|
-
|
441
|
-
|
539
|
+
if (bytes_read == -1) {
|
540
|
+
rb_raise(rb_eRuntimeError, "read failed: %d", errno);
|
541
|
+
}
|
442
542
|
|
443
|
-
|
543
|
+
zkrb_debug_inst(self, "read %zd bytes from the queue (%p)'s pipe", bytes_read, zk->queue);
|
544
|
+
|
545
|
+
continue;
|
546
|
+
}
|
444
547
|
}
|
445
548
|
|
446
549
|
VALUE hash = zkrb_event_to_ruby(event);
|
447
550
|
zkrb_event_free(event);
|
448
551
|
return hash;
|
449
552
|
}
|
553
|
+
|
554
|
+
error:
|
555
|
+
return Qnil;
|
450
556
|
}
|
451
557
|
|
452
558
|
static VALUE method_has_events(VALUE self) {
|
@@ -457,27 +563,39 @@ static VALUE method_has_events(VALUE self) {
|
|
457
563
|
return rb_event;
|
458
564
|
}
|
459
565
|
|
460
|
-
static VALUE method_client_id(VALUE self) {
|
461
|
-
FETCH_DATA_PTR(self, zk);
|
462
|
-
const clientid_t *id = zoo_client_id(zk->zh);
|
463
|
-
return UINT2NUM(id->client_id);
|
464
|
-
}
|
465
566
|
|
466
|
-
|
467
|
-
|
567
|
+
// wake up the event loop, used when shutting down
|
568
|
+
static VALUE method_wake_event_loop_bang(VALUE self) {
|
569
|
+
FETCH_DATA_PTR(self, zk);
|
468
570
|
|
469
|
-
zk->
|
571
|
+
zkrb_debug_inst(self, "Waking event loop: %p", zk->queue);
|
470
572
|
zkrb_signal(zk->queue);
|
471
573
|
|
472
574
|
return Qnil;
|
473
|
-
}
|
575
|
+
};
|
474
576
|
|
475
|
-
static VALUE
|
577
|
+
static VALUE method_close_handle(VALUE self) {
|
476
578
|
FETCH_DATA_PTR(self, zk);
|
477
579
|
|
580
|
+
if (ZKRBDebugging) {
|
581
|
+
/* fprintf(stderr, "CLOSING ZK INSTANCE: obj_id %lx", FIX2LONG(rb_obj_id(self)));*/
|
582
|
+
zkrb_debug_inst(self, "CLOSING_ZK_INSTANCE");
|
583
|
+
print_zkrb_instance_data(zk);
|
584
|
+
}
|
585
|
+
|
586
|
+
// this is a value on the ruby side we can check to see if destroy_zkrb_instance
|
587
|
+
// has been called
|
588
|
+
rb_iv_set(self, "@_closed", Qtrue);
|
589
|
+
|
590
|
+
zkrb_debug_inst(self, "calling destroy_zkrb_instance");
|
591
|
+
|
478
592
|
/* Note that after zookeeper_close() returns, ZK handle is invalid */
|
479
593
|
int rc = destroy_zkrb_instance(zk);
|
480
|
-
|
594
|
+
|
595
|
+
zkrb_debug("destroy_zkrb_instance returned: %d", rc);
|
596
|
+
|
597
|
+
return Qnil;
|
598
|
+
/* return INT2FIX(rc);*/
|
481
599
|
}
|
482
600
|
|
483
601
|
static VALUE method_deterministic_conn_order(VALUE self, VALUE yn) {
|
@@ -490,7 +608,7 @@ static VALUE method_is_unrecoverable(VALUE self) {
|
|
490
608
|
return is_unrecoverable(zk->zh) == ZINVALIDSTATE ? Qtrue : Qfalse;
|
491
609
|
}
|
492
610
|
|
493
|
-
static VALUE
|
611
|
+
static VALUE method_zkrb_state(VALUE self) {
|
494
612
|
FETCH_DATA_PTR(self, zk);
|
495
613
|
return INT2NUM(zoo_state(zk->zh));
|
496
614
|
}
|
@@ -500,8 +618,30 @@ static VALUE method_recv_timeout(VALUE self) {
|
|
500
618
|
return INT2NUM(zoo_recv_timeout(zk->zh));
|
501
619
|
}
|
502
620
|
|
503
|
-
|
504
|
-
|
621
|
+
/*static VALUE method_client_id(VALUE self) {*/
|
622
|
+
/* FETCH_DATA_PTR(self, zk);*/
|
623
|
+
/* const clientid_t *id = zoo_client_id(zk->zh);*/
|
624
|
+
/* return UINT2NUM(id->client_id);*/
|
625
|
+
/*}*/
|
626
|
+
|
627
|
+
|
628
|
+
// returns a CZookeeper::ClientId object with the values set for session_id and passwd
|
629
|
+
static VALUE method_client_id(VALUE self) {
|
630
|
+
FETCH_DATA_PTR(self, zk);
|
631
|
+
const clientid_t *cid = zoo_client_id(zk->zh);
|
632
|
+
|
633
|
+
VALUE session_id = LL2NUM(cid->client_id);
|
634
|
+
VALUE passwd = rb_str_new2(cid->passwd);
|
635
|
+
|
636
|
+
VALUE client_id_obj = rb_class_new_instance(0, RARRAY_PTR(rb_ary_new()), ZookeeperClientId);
|
637
|
+
|
638
|
+
rb_funcall(client_id_obj, rb_intern("session_id="), 1, session_id);
|
639
|
+
rb_funcall(client_id_obj, rb_intern("passwd="), 1, passwd);
|
640
|
+
|
641
|
+
return client_id_obj;
|
642
|
+
}
|
643
|
+
|
644
|
+
static VALUE klass_method_zkrb_set_debug_level(VALUE klass, VALUE level) {
|
505
645
|
Check_Type(level, T_FIXNUM);
|
506
646
|
ZKRBDebugging = (FIX2INT(level) == ZOO_LOG_LEVEL_DEBUG);
|
507
647
|
zoo_set_debug_level(FIX2INT(level));
|
@@ -518,7 +658,8 @@ static void zkrb_define_methods(void) {
|
|
518
658
|
#define DEFINE_CLASS_METHOD(method, args) { \
|
519
659
|
rb_define_singleton_method(Zookeeper, #method, method_ ## method, args); }
|
520
660
|
|
521
|
-
|
661
|
+
// the number after the method name should be actual arity of C function - 1
|
662
|
+
DEFINE_METHOD(zkrb_init, -1);
|
522
663
|
DEFINE_METHOD(get_children, 4);
|
523
664
|
DEFINE_METHOD(exists, 4);
|
524
665
|
DEFINE_METHOD(create, 6);
|
@@ -528,27 +669,57 @@ static void zkrb_define_methods(void) {
|
|
528
669
|
DEFINE_METHOD(set_acl, 5);
|
529
670
|
DEFINE_METHOD(get_acl, 3);
|
530
671
|
DEFINE_METHOD(client_id, 0);
|
531
|
-
DEFINE_METHOD(
|
532
|
-
DEFINE_METHOD(close, 0);
|
672
|
+
DEFINE_METHOD(close_handle, 0);
|
533
673
|
DEFINE_METHOD(deterministic_conn_order, 1);
|
534
674
|
DEFINE_METHOD(is_unrecoverable, 0);
|
535
675
|
DEFINE_METHOD(recv_timeout, 1);
|
536
|
-
DEFINE_METHOD(
|
676
|
+
DEFINE_METHOD(zkrb_state, 0);
|
677
|
+
DEFINE_METHOD(sync, 2);
|
678
|
+
|
537
679
|
// TODO
|
538
680
|
// DEFINE_METHOD(add_auth, 3);
|
539
|
-
// DEFINE_METHOD(async, 1);
|
540
681
|
|
541
682
|
// methods for the ruby-side event manager
|
542
|
-
DEFINE_METHOD(get_next_event,
|
683
|
+
DEFINE_METHOD(get_next_event, 1);
|
543
684
|
DEFINE_METHOD(has_events, 0);
|
544
685
|
|
545
686
|
// Make these class methods?
|
546
|
-
DEFINE_METHOD(set_debug_level, 1);
|
547
687
|
DEFINE_METHOD(zerror, 1);
|
688
|
+
|
689
|
+
rb_define_singleton_method(Zookeeper, "set_zkrb_debug_level", klass_method_zkrb_set_debug_level, 1);
|
690
|
+
|
691
|
+
rb_attr(Zookeeper, rb_intern("selectable_io"), 1, 0, Qtrue);
|
692
|
+
rb_define_method(Zookeeper, "wake_event_loop!", method_wake_event_loop_bang, 0);
|
693
|
+
|
548
694
|
}
|
695
|
+
|
696
|
+
// class CZookeeper::ClientId
|
697
|
+
// attr_accessor :session_id, :passwd
|
698
|
+
//
|
699
|
+
// def initialize(session_id, passwd)
|
700
|
+
// @session_id = session_id
|
701
|
+
// @passwd = passwd
|
702
|
+
// end
|
703
|
+
// end
|
704
|
+
|
705
|
+
static VALUE zkrb_client_id_method_initialize(VALUE self) {
|
706
|
+
rb_iv_set(self, "@session_id", Qnil);
|
707
|
+
rb_iv_set(self, "@passwd", Qnil);
|
708
|
+
return Qnil;
|
709
|
+
}
|
710
|
+
|
711
|
+
|
549
712
|
void Init_zookeeper_c() {
|
550
713
|
ZKRBDebugging = 0;
|
714
|
+
|
551
715
|
/* initialize Zookeeper class */
|
552
716
|
Zookeeper = rb_define_class("CZookeeper", rb_cObject);
|
553
717
|
zkrb_define_methods();
|
718
|
+
|
719
|
+
ZookeeperClientId = rb_define_class_under(Zookeeper, "ClientId", rb_cObject);
|
720
|
+
rb_define_method(ZookeeperClientId, "initialize", zkrb_client_id_method_initialize, 0);
|
721
|
+
rb_define_attr(ZookeeperClientId, "session_id", 1, 1);
|
722
|
+
rb_define_attr(ZookeeperClientId, "passwd", 1, 1);
|
554
723
|
}
|
724
|
+
|
725
|
+
// vim:ts=2:sw=2:sts=2:et
|