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/extconf.rb
CHANGED
@@ -6,16 +6,31 @@ HERE = File.expand_path(File.dirname(__FILE__))
|
|
6
6
|
BUNDLE = Dir.glob("zkc-*.tar.gz").first
|
7
7
|
BUNDLE_PATH = "c"
|
8
8
|
|
9
|
-
$
|
10
|
-
|
9
|
+
$EXTRA_CONF = ''
|
10
|
+
|
11
|
+
# CLANG!!!! jeez, if apple would only *stop* "thinking different"
|
12
|
+
if cc = RbConfig::CONFIG['CC'] && cc =~ /^gcc/
|
13
|
+
$CC = cc
|
14
|
+
$EXTRA_CONF = "#{$EXTRA_CONF} CC=#{$CC}"
|
15
|
+
end
|
16
|
+
|
17
|
+
$CFLAGS = "#{$CFLAGS}".gsub("$(cflags)", "").gsub("-arch ppc", "")
|
18
|
+
$LDFLAGS = "#{$LDFLAGS}".gsub("$(ldflags)", "").gsub("-arch ppc", "")
|
11
19
|
$CXXFLAGS = " -std=gnu++98 #{$CFLAGS}"
|
12
20
|
$CPPFLAGS = $ARCH_FLAG = $DLDFLAGS = ""
|
13
21
|
|
14
|
-
if
|
15
|
-
|
16
|
-
|
17
|
-
|
22
|
+
if RUBY_VERSION == '1.8.7'
|
23
|
+
$CFLAGS << ' -DZKRB_RUBY_187'
|
24
|
+
end
|
25
|
+
|
26
|
+
ZK_DEBUG = (ENV['DEBUG'] or ARGV.any? { |arg| arg == '--debug' })
|
27
|
+
DEBUG_CFLAGS = " -O0 -ggdb3 -DHAVE_DEBUG"
|
28
|
+
|
29
|
+
if ZK_DEBUG
|
30
|
+
$stderr.puts "*** Setting debug flags. ***"
|
31
|
+
$EXTRA_CONF = "#{$EXTRA_CONF} --enable-debug"
|
18
32
|
$CFLAGS.gsub!(/ -O[^0] /, ' ')
|
33
|
+
$CFLAGS << DEBUG_CFLAGS
|
19
34
|
end
|
20
35
|
|
21
36
|
$includes = " -I#{HERE}/include"
|
@@ -25,23 +40,35 @@ $LDFLAGS = "#{$libraries} #{$LDFLAGS}"
|
|
25
40
|
$LIBPATH = ["#{HERE}/lib"]
|
26
41
|
$DEFLIBPATH = []
|
27
42
|
|
43
|
+
def safe_sh(cmd)
|
44
|
+
puts cmd
|
45
|
+
system(cmd)
|
46
|
+
unless $?.exited? and $?.success?
|
47
|
+
raise "command failed! #{cmd}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
28
51
|
Dir.chdir(HERE) do
|
29
52
|
if File.exist?("lib")
|
30
|
-
puts "Zkc already built; run 'rake
|
53
|
+
puts "Zkc already built; run 'rake clobber' in ext/ first if you need to rebuild."
|
31
54
|
else
|
32
55
|
puts "Building zkc."
|
33
|
-
puts(cmd = "tar xzf #{BUNDLE} 2>&1")
|
34
|
-
raise "'#{cmd}' failed" unless system(cmd)
|
35
56
|
|
36
|
-
|
37
|
-
puts(cmd = "
|
38
|
-
raise "'#{cmd}' failed" unless system(cmd)
|
39
|
-
puts(cmd = "make CXXFLAGS='#{$CXXFLAGS}' CFLAGS='-fPIC #{$CFLAGS}' LDFLAGS='-fPIC #{$LDFLAGS}' || true 2>&1")
|
40
|
-
raise "'#{cmd}' failed" unless system(cmd)
|
41
|
-
puts(cmd = "make install || true 2>&1")
|
57
|
+
unless File.exists?('c')
|
58
|
+
puts(cmd = "tar xzf #{BUNDLE} 2>&1")
|
42
59
|
raise "'#{cmd}' failed" unless system(cmd)
|
43
60
|
end
|
44
61
|
|
62
|
+
Dir.chdir(BUNDLE_PATH) do
|
63
|
+
configure = "./configure --prefix=#{HERE} --with-pic --without-cppunit --disable-dependency-tracking #{$EXTRA_CONF} 2>&1"
|
64
|
+
|
65
|
+
configure = "env CFLAGS='#{DEBUG_CFLAGS}' #{configure}" if ZK_DEBUG
|
66
|
+
|
67
|
+
safe_sh(configure)
|
68
|
+
safe_sh("make 2>&1")
|
69
|
+
safe_sh("make install 2>&1")
|
70
|
+
end
|
71
|
+
|
45
72
|
system("rm -rf #{BUNDLE_PATH}") unless ENV['DEBUG'] or ENV['DEV']
|
46
73
|
end
|
47
74
|
end
|
@@ -53,4 +80,6 @@ Dir.chdir("#{HERE}/lib") do
|
|
53
80
|
end
|
54
81
|
$LIBS << " -lzookeeper_mt_gem"
|
55
82
|
|
83
|
+
|
56
84
|
create_makefile 'zookeeper_c'
|
85
|
+
|
@@ -0,0 +1,316 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
=begin
|
4
|
+
the idea here is to take each zoo_* function declaration in the header file, and turn it into
|
5
|
+
a calling arguments struct, a wrapper function and a macro for packing the values.
|
6
|
+
|
7
|
+
so for:
|
8
|
+
|
9
|
+
ZOOAPI int zoo_acreate(zhandle_t *zh, const char *path, const char *value,
|
10
|
+
int valuelen, const struct ACL_vector *acl, int flags,
|
11
|
+
string_completion_t completion, const void *data);
|
12
|
+
|
13
|
+
we want
|
14
|
+
|
15
|
+
typedef struct {
|
16
|
+
zhandle_t *zh;
|
17
|
+
const char *path;
|
18
|
+
const char *value;
|
19
|
+
int valuelen;
|
20
|
+
const struct ACL_vector *acl;
|
21
|
+
int flags;
|
22
|
+
string_completion_t completion;
|
23
|
+
const void *data;
|
24
|
+
} zkrb_zoo_acreate_args_t;
|
25
|
+
|
26
|
+
static VALUE zkrb_gvl_zoo_acreate(void *data) {
|
27
|
+
zkrb_zoo_acreate_args_t *a = (zkrb_zoo_acreate_args_t *)data;
|
28
|
+
|
29
|
+
a->rc = zoo_acreate(a->zh, a->path, a->value, a->valuelen, a->acl, a->flags, a->completion, a->data);
|
30
|
+
|
31
|
+
return Qnil;
|
32
|
+
}
|
33
|
+
|
34
|
+
static int zkrb_call_zoo_acreate(zhandle_t *zh, const char *path, const char *value,
|
35
|
+
int valuelen, const struct ACL_vector *acl, int flags,
|
36
|
+
string_completion_t completion, const void *data) {
|
37
|
+
|
38
|
+
zkrb_zoo_acreate_args_t args = {
|
39
|
+
.rc = ZKRB_FAIL,
|
40
|
+
.zh = zh,
|
41
|
+
.path = path,
|
42
|
+
.value = value,
|
43
|
+
.valuelen = valuelen,
|
44
|
+
.acl = acl,
|
45
|
+
.flags = flags,
|
46
|
+
.completion = completion,
|
47
|
+
.data = data
|
48
|
+
};
|
49
|
+
|
50
|
+
zkrb_thread_blocking_region(zkrb_gvl_zoo_acreate, (void *)&args);
|
51
|
+
|
52
|
+
return args.rc;
|
53
|
+
}
|
54
|
+
|
55
|
+
=end
|
56
|
+
|
57
|
+
REGEXP = /^ZOOAPI int (zoo_[^(]+)\(([^)]+)\);$/m
|
58
|
+
|
59
|
+
require 'forwardable'
|
60
|
+
require 'stringio'
|
61
|
+
|
62
|
+
ZKRB_WRAPPER_H_PATH = File.expand_path('../zkrb_wrapper.h', __FILE__)
|
63
|
+
ZKRB_WRAPPER_C_PATH = File.expand_path('../zkrb_wrapper.c', __FILE__)
|
64
|
+
|
65
|
+
# the struct that holds the call args for zoo_fn_name
|
66
|
+
class CallStruct
|
67
|
+
attr_reader :zoo_fn_name, :typed_args, :name
|
68
|
+
|
69
|
+
def initialize(zoo_fn_name, typed_args)
|
70
|
+
@zoo_fn_name, @typed_args = zoo_fn_name, typed_args
|
71
|
+
@name = "zkrb_#{zoo_fn_name}_args_t"
|
72
|
+
end
|
73
|
+
|
74
|
+
def body
|
75
|
+
@body ||= (
|
76
|
+
lines = ["typedef struct {"]
|
77
|
+
lines += typed_args.map{|n| " #{n};"}
|
78
|
+
lines << " int rc;"
|
79
|
+
lines << "} #{name};"
|
80
|
+
lines.join("\n")
|
81
|
+
)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
module MemberNames
|
86
|
+
def member_names
|
87
|
+
@member_names ||= typed_args.map { |n| n.split(/[ *]/).last }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# the zkrb_gvl_zoo_* function
|
92
|
+
class WrapperFunction
|
93
|
+
extend Forwardable
|
94
|
+
include MemberNames
|
95
|
+
|
96
|
+
PREFIX = 'zkrb_gvl'
|
97
|
+
|
98
|
+
def_delegators :struct, :typed_args
|
99
|
+
|
100
|
+
attr_reader :struct, :name, :zoo_fn_name
|
101
|
+
|
102
|
+
def initialize(zoo_fn_name, struct)
|
103
|
+
@zoo_fn_name = zoo_fn_name
|
104
|
+
@struct = struct
|
105
|
+
@name = "#{PREFIX}_#{zoo_fn_name}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def fn_signature
|
109
|
+
@fn_signature ||= "static VALUE #{name}(void *data)"
|
110
|
+
end
|
111
|
+
|
112
|
+
def body
|
113
|
+
@body ||= (
|
114
|
+
lines = ["#{fn_signature} {"]
|
115
|
+
lines << " #{struct.name} *a = (#{struct.name} *)data;"
|
116
|
+
|
117
|
+
funcall = " a->rc = #{zoo_fn_name}("
|
118
|
+
funcall << member_names.map { |m| "a->#{m}" }.join(', ')
|
119
|
+
funcall << ');'
|
120
|
+
|
121
|
+
lines << funcall
|
122
|
+
|
123
|
+
lines << " return Qnil;"
|
124
|
+
lines << "}"
|
125
|
+
lines.join("\n")
|
126
|
+
)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# the zkrb_call_zoo_* function
|
131
|
+
class CallingFunction
|
132
|
+
extend Forwardable
|
133
|
+
include MemberNames
|
134
|
+
|
135
|
+
PREFIX = 'zkrb_call'
|
136
|
+
|
137
|
+
def_delegators :struct, :typed_args
|
138
|
+
|
139
|
+
attr_reader :struct, :wrapper_fn, :zoo_fn_name, :name
|
140
|
+
|
141
|
+
def initialize(zoo_fn_name, struct, wrapper_fn)
|
142
|
+
@zoo_fn_name, @struct, @wrapper_fn = zoo_fn_name, struct, wrapper_fn
|
143
|
+
|
144
|
+
@name = "#{PREFIX}_#{zoo_fn_name}"
|
145
|
+
end
|
146
|
+
|
147
|
+
def fn_signature
|
148
|
+
@fn_signature ||= "int #{name}(#{typed_args.join(', ')})"
|
149
|
+
end
|
150
|
+
|
151
|
+
def initializer_lines
|
152
|
+
@initializer_lines ||= member_names.map { |n| " .#{n} = #{n}" }.join(",\n")
|
153
|
+
end
|
154
|
+
|
155
|
+
def top
|
156
|
+
<<-EOS
|
157
|
+
// wrapper that calls #{zoo_fn_name} via #{wrapper_fn.name} inside rb_thread_blocking_region
|
158
|
+
#{fn_signature} {
|
159
|
+
#{struct.name} args = {
|
160
|
+
.rc = ZKRB_FAIL,
|
161
|
+
#{initializer_lines}
|
162
|
+
};
|
163
|
+
EOS
|
164
|
+
end
|
165
|
+
|
166
|
+
def rb_thread_blocking_region_call
|
167
|
+
" zkrb_thread_blocking_region(#{wrapper_fn.name}, (void *)&args);"
|
168
|
+
end
|
169
|
+
|
170
|
+
def bottom
|
171
|
+
<<-EOS
|
172
|
+
|
173
|
+
return args.rc;
|
174
|
+
}
|
175
|
+
EOS
|
176
|
+
end
|
177
|
+
|
178
|
+
def body
|
179
|
+
@body ||= [top, rb_thread_blocking_region_call, bottom].join("\n")
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
class GeneratedCode < Struct.new(:structs, :wrapper_fns, :calling_fns)
|
184
|
+
def initialize(*a)
|
185
|
+
super
|
186
|
+
|
187
|
+
self.structs ||= []
|
188
|
+
self.wrapper_fns ||= []
|
189
|
+
self.calling_fns ||= []
|
190
|
+
end
|
191
|
+
|
192
|
+
def self.from_zookeeper_h(text)
|
193
|
+
new.tap do |code|
|
194
|
+
while true
|
195
|
+
break unless text =~ REGEXP
|
196
|
+
text = $~.post_match
|
197
|
+
|
198
|
+
zoo_fn_name, argstr = $1
|
199
|
+
argstr = $2
|
200
|
+
|
201
|
+
typed_args = argstr.split(',').map(&:strip)
|
202
|
+
|
203
|
+
# gah, fix up zoo_aset_acl which has a void_completion_t with no name assigned
|
204
|
+
if zoo_fn_name == 'zoo_aset_acl'
|
205
|
+
if idx = typed_args.index('void_completion_t')
|
206
|
+
typed_args[idx] = 'void_completion_t completion'
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
struct = CallStruct.new(zoo_fn_name, typed_args)
|
211
|
+
wrapper_fn = WrapperFunction.new(zoo_fn_name, struct)
|
212
|
+
calling_fn = CallingFunction.new(zoo_fn_name, struct, wrapper_fn)
|
213
|
+
|
214
|
+
code.structs << struct
|
215
|
+
code.wrapper_fns << wrapper_fn
|
216
|
+
code.calling_fns << calling_fn
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def render_header_file(code)
|
223
|
+
StringIO.new('zkrb_wrapper.h', 'w').tap do |fp|
|
224
|
+
fp.puts <<-EOS
|
225
|
+
#ifndef ZKRB_WRAPPER_H
|
226
|
+
#define ZKRB_WRAPPER_H
|
227
|
+
#if 0
|
228
|
+
|
229
|
+
AUTOGENERATED BY #{File.basename(__FILE__)}
|
230
|
+
|
231
|
+
#endif
|
232
|
+
|
233
|
+
#include "ruby.h"
|
234
|
+
#include "c-client-src/zookeeper.h"
|
235
|
+
#include "zkrb_wrapper_compat.h"
|
236
|
+
#include "dbg.h"
|
237
|
+
|
238
|
+
#define ZKRB_FAIL -1
|
239
|
+
|
240
|
+
EOS
|
241
|
+
|
242
|
+
code.structs.each do |struct|
|
243
|
+
fp.puts(struct.body)
|
244
|
+
fp.puts
|
245
|
+
end
|
246
|
+
|
247
|
+
code.calling_fns.each do |cf|
|
248
|
+
fp.puts "#{cf.fn_signature};"
|
249
|
+
end
|
250
|
+
|
251
|
+
fp.puts <<-EOS
|
252
|
+
|
253
|
+
#endif /* ZKRB_WRAPPER_H */
|
254
|
+
EOS
|
255
|
+
|
256
|
+
end.string
|
257
|
+
end
|
258
|
+
|
259
|
+
def render_c_file(code)
|
260
|
+
StringIO.new('zkrb_wrapper.c', 'w').tap do |fp|
|
261
|
+
fp.puts <<-EOS
|
262
|
+
/*
|
263
|
+
|
264
|
+
Autogenerated boilerplate wrappers around zoo_* function calls necessary for using
|
265
|
+
rb_thread_blocking_region to release the GIL when calling native code.
|
266
|
+
|
267
|
+
generated by ext/#{File.basename(__FILE__)}
|
268
|
+
|
269
|
+
*/
|
270
|
+
|
271
|
+
#include "ruby.h"
|
272
|
+
#include "zkrb_wrapper.h"
|
273
|
+
#include <errno.h>
|
274
|
+
#include <stdio.h>
|
275
|
+
#include <stdlib.h>
|
276
|
+
|
277
|
+
EOS
|
278
|
+
|
279
|
+
code.wrapper_fns.zip(code.calling_fns) do |wrap_fn, call_fn|
|
280
|
+
fp.puts "#{wrap_fn.body}\n\n"
|
281
|
+
fp.puts "#{call_fn.body}\n\n"
|
282
|
+
end
|
283
|
+
|
284
|
+
end.string
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
def help!
|
289
|
+
$stderr.puts "usage: #{File.basename(__FILE__)} {all|headers|code}"
|
290
|
+
exit 1
|
291
|
+
end
|
292
|
+
|
293
|
+
def main
|
294
|
+
help! if ARGV.empty?
|
295
|
+
|
296
|
+
text = File.read('c/include/zookeeper.h')
|
297
|
+
code = GeneratedCode.from_zookeeper_h(text)
|
298
|
+
|
299
|
+
cmd = ARGV.first
|
300
|
+
|
301
|
+
help! unless %w[headers all code].include?(cmd)
|
302
|
+
|
303
|
+
if %w[headers all].include?(cmd)
|
304
|
+
$stderr.puts "writing #{ZKRB_WRAPPER_H_PATH}"
|
305
|
+
File.open(ZKRB_WRAPPER_H_PATH, 'w') { |fp| fp.write(render_header_file(code)) }
|
306
|
+
end
|
307
|
+
|
308
|
+
if %w[code all].include?(cmd)
|
309
|
+
$stderr.puts "writing #{ZKRB_WRAPPER_C_PATH}"
|
310
|
+
File.open(ZKRB_WRAPPER_C_PATH, 'w') { |fp| fp.write(render_c_file(code)) }
|
311
|
+
end
|
312
|
+
|
313
|
+
end
|
314
|
+
|
315
|
+
main
|
316
|
+
|
Binary file
|