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.
Files changed (48) hide show
  1. data/.gitignore +10 -0
  2. data/CHANGELOG +95 -0
  3. data/Gemfile +17 -0
  4. data/Manifest +8 -2
  5. data/README.markdown +59 -0
  6. data/Rakefile +137 -7
  7. data/ext/.gitignore +6 -0
  8. data/ext/Rakefile +51 -0
  9. data/ext/c_zookeeper.rb +212 -0
  10. data/ext/dbg.h +53 -0
  11. data/ext/depend +5 -0
  12. data/ext/extconf.rb +44 -15
  13. data/ext/generate_gvl_code.rb +316 -0
  14. data/ext/zkc-3.3.5.tar.gz +0 -0
  15. data/ext/zkrb_wrapper.c +731 -0
  16. data/ext/zkrb_wrapper.h +330 -0
  17. data/ext/zkrb_wrapper_compat.c +15 -0
  18. data/ext/zkrb_wrapper_compat.h +11 -0
  19. data/ext/zookeeper_base.rb +211 -0
  20. data/ext/zookeeper_c.c +268 -97
  21. data/ext/zookeeper_lib.c +157 -92
  22. data/ext/zookeeper_lib.h +12 -6
  23. data/java/zookeeper_base.rb +477 -0
  24. data/lib/zookeeper/acls.rb +10 -1
  25. data/lib/zookeeper/callbacks.rb +5 -3
  26. data/lib/zookeeper/common/queue_with_pipe.rb +78 -0
  27. data/lib/zookeeper/common.rb +174 -0
  28. data/lib/zookeeper/constants.rb +31 -28
  29. data/lib/zookeeper/em_client.rb +55 -0
  30. data/lib/zookeeper/exceptions.rb +10 -2
  31. data/lib/zookeeper/stat.rb +11 -2
  32. data/lib/zookeeper/version.rb +6 -0
  33. data/lib/zookeeper.rb +155 -122
  34. data/notes.txt +14 -0
  35. data/spec/c_zookeeper_spec.rb +50 -0
  36. data/spec/chrooted_connection_spec.rb +81 -0
  37. data/spec/default_watcher_spec.rb +41 -0
  38. data/spec/em_spec.rb +51 -0
  39. data/spec/log4j.properties +17 -0
  40. data/spec/shared/all_success_return_values.rb +10 -0
  41. data/spec/shared/connection_examples.rb +1018 -0
  42. data/spec/spec_helper.rb +119 -0
  43. data/spec/support/progress_formatter.rb +15 -0
  44. data/spec/zookeeper_spec.rb +24 -0
  45. data/zookeeper.gemspec +37 -25
  46. metadata +78 -34
  47. data/README +0 -42
  48. 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
- $CFLAGS = "#{RbConfig::CONFIG['CFLAGS']} #{$CFLAGS}".gsub("$(cflags)", "").gsub("-arch ppc", "")
10
- $LDFLAGS = "#{RbConfig::CONFIG['LDFLAGS']} #{$LDFLAGS}".gsub("$(ldflags)", "").gsub("-arch ppc", "")
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 ENV['DEBUG']
15
- puts "Setting debug flags."
16
- $CFLAGS << " -O0 -ggdb -DHAVE_DEBUG"
17
- $EXTRA_CONF = " --enable-debug"
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 clean' first if you need to rebuild."
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
- Dir.chdir(BUNDLE_PATH) do
37
- puts(cmd = "env CC=gcc CXX=g++ CFLAGS='-fPIC #{$CFLAGS}' LDFLAGS='-fPIC #{$LDFLAGS}' ./configure --prefix=#{HERE} --without-cppunit --disable-dependency-tracking #{$EXTRA_CONF} 2>&1")
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