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/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ *.gem
2
+ *.o
3
+ *.so
4
+ *~
5
+ *.log
6
+ Makefile
7
+ pkg
8
+ zookeeper.gemspec
9
+ Gemfile.*
10
+ tmp/
data/CHANGELOG CHANGED
@@ -1,3 +1,97 @@
1
+ v0.9.3 Event thread shutdown fix, Windows compatibility fix
2
+
3
+ * Use a 'shutdown thread' to coordinate cleanup if close is called from the
4
+ event thread (prevents deadlock)
5
+
6
+ * Default Logger now uses $stderr instead of opening /dev/null [#16]
7
+
8
+ * Gemfile/gemspec/Rakefile refactoring.
9
+
10
+ v0.9.2 More efficient and simpler wrappers for GIL release
11
+
12
+ * After a code review by Andrew Wason (rectalogic), use a much simpler
13
+ technique for creating the arg structs and passing them to the
14
+ zkrb_gvl_* functions. No malloc(), no free(), no problem.
15
+
16
+ v0.9.1 see v0.8.4 notes, same patch
17
+
18
+ v0.9.0 RELEASE THE KRAK..er, GIL!!
19
+
20
+ * In >= 1.9.2 the ruby interpreter allows you to release the GIL when
21
+ calling into native code, sounds like a good idea.
22
+
23
+ This release makes use of that code by parsing the zookeeper.h header file
24
+ and extracting the method signatures of all relevant zoo_* functions, then
25
+ generating boilerplate that allows us to call those functions via the
26
+ rb_thread_blocking_region function.
27
+
28
+ 1.8.7 compatibility is maintained by stubbing out that functionality if built
29
+ under 1.8.7.
30
+
31
+ * 1.8.7 is deprecated! I will continue to support 1.8.7 for the near future
32
+ but sometime soon, you're gonna have to upgrade.
33
+
34
+ v0.8.4 fix NameError, require 'forwardable'
35
+
36
+ * Really not sure why this didn't come up in tests
37
+
38
+ * issue here https://github.com/slyphon/zk/issues/22
39
+
40
+ v0.8.3 fix NonLocalJump exception in event delivery thread shutdown code
41
+
42
+ * hit a corner case where we're waiting for the zkc handle setup
43
+ and the user decides to shutdown, but before we've had a chance
44
+ to enter the delivery loop.
45
+
46
+ * Cleaned up some nasty code in ZookeeperConstants
47
+
48
+ * removed ZookeeperConstants#print_events and ZookeeperConstants#print_states
49
+
50
+ * changed EVENT_TYPE_NAMES and EVENT_STATE_NAMES in ZookeeperConstants
51
+ to use string values instead of symbols
52
+
53
+ v0.8.2 fix close after a fork()
54
+
55
+ * The dispatch thread will be dead in this situation, so we need to
56
+ check to see if it's already dead before waiting on it to exit.
57
+
58
+ v0.8.1 Java client fix, silence warnings
59
+
60
+ v0.8.0 Refactor C implementaion, EventMachine client
61
+
62
+ * separated CZookeeper and ZookeeperBase implementation
63
+
64
+ This solves issues with reopen not working properly, makes for a much
65
+ cleaner event delivery implementation. ZookeeperBase controls the lifecycle
66
+ of the event dispatch thread now, rather than it being tied to CZookeeper.
67
+
68
+ * added support for the 'sync' API call
69
+
70
+ * Refactored zookeeper_c.c and zookeeper_lib.c
71
+
72
+ More error checking in zookeeper_lib.c and restructure some things to make
73
+ logic easier to follow
74
+
75
+ Fix bug in method_get_next_event that made the shutdown case so complicated
76
+
77
+ * Massively simplified EMClient implementation
78
+
79
+ Rather than trying to hook the IO used by zookeeper_lib to notify zookeeper_c
80
+ about event availabiltiy directly into EventMachine, use the same event delivery
81
+ thread, but wrap the dispatch call in EM.schedule.
82
+
83
+ * Improve implementation of spin-lock-esque code that waits for the connection to be
84
+ established before returning.
85
+
86
+ This cut the test runtime down from 1m 20s to 2s.
87
+
88
+ * Java client refactoring, similar correctness changes
89
+
90
+ * Change ZookeeperException base class to StandardError instead of Exception
91
+
92
+
93
+ v0.4.5 Upgrade to ZooKeeper 3.3.3
94
+
1
95
  v0.4.4 Fix race condition on close, possible data corruption on async get.
2
96
 
3
97
  v0.4.3 Fix a handful of memory-related bugs, fix SIGSEGV on master change, reduce latency of event handling, fix compilation on OSX.
@@ -22,3 +116,4 @@ v0.2. Bundle C dependencies, like memcached.gem.
22
116
 
23
117
  v0.1. First release.
24
118
 
119
+ # vim:ft=text:ts=2:sw=2:et
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "rspec", "~> 2.8.0"
7
+ gem 'flexmock', '~> 0.8.11'
8
+ gem 'eventmachine', '1.0.0.beta.4'
9
+ gem 'evented-spec', '~> 0.9.0'
10
+ end
11
+
12
+ group :development do
13
+ gem 'rake', '~> 0.9.0'
14
+ gem 'pry'
15
+ end
16
+
17
+ # vim:ft=ruby
data/Manifest CHANGED
@@ -1,23 +1,29 @@
1
1
  CHANGELOG
2
2
  LICENSE
3
+ Manifest
3
4
  README
4
5
  Rakefile
5
6
  examples/cloud_config.rb
6
7
  ext/extconf.rb
7
- ext/zkc-3.3.2.tar.gz
8
+ ext/zkc-3.3.4.tar.gz
9
+ ext/zookeeper_base.rb
8
10
  ext/zookeeper_c.c
9
11
  ext/zookeeper_lib.c
10
12
  ext/zookeeper_lib.h
13
+ java/zookeeper_base.rb
11
14
  lib/zookeeper.rb
12
15
  lib/zookeeper/acls.rb
13
16
  lib/zookeeper/callbacks.rb
17
+ lib/zookeeper/common.rb
14
18
  lib/zookeeper/constants.rb
15
19
  lib/zookeeper/exceptions.rb
16
20
  lib/zookeeper/stat.rb
21
+ spec/log4j.properties
22
+ spec/spec_helper.rb
23
+ spec/zookeeper_spec.rb
17
24
  test/test_basic.rb
18
25
  test/test_callback1.rb
19
26
  test/test_close.rb
20
27
  test/test_esoteric.rb
21
28
  test/test_watcher1.rb
22
29
  test/test_watcher2.rb
23
- Manifest
data/README.markdown ADDED
@@ -0,0 +1,59 @@
1
+ # zookeeper #
2
+
3
+ An interface to the Zookeeper cluster coordination server.
4
+
5
+ For a higher-level interface with a more convenient API and features such as locks, have a look at [ZK](https://github.com/slyphon/zk) (also available is [ZK-EventMachine](https://github.com/slyphon/zk-eventmachine) for those who prefer async).
6
+
7
+ ## Big Plans for 1.0 ##
8
+
9
+ The 1.0 release will feature a reorganization of the heirarchy. There will be a single top-level `Zookeeper` namespace (as opposed to the current layout, with 5-6 different top-level constants), and for the next several releases, there will be a backwards compatible require for users that still need to use the old names.
10
+
11
+ ## License
12
+
13
+ Copyright 2008 Phillip Pearson, and 2010 Twitter, Inc.
14
+ Licensed under the MIT License. See the included LICENSE file.
15
+
16
+ Portions copyright 2008-2010 the Apache Software Foundation, licensed under the
17
+ Apache 2 license, and used with permission.
18
+
19
+ Portions contributed to the open source community by HPDC, L.P.
20
+
21
+ ## Install
22
+
23
+ sudo gem install zookeeper
24
+
25
+ ## Usage
26
+
27
+ Connect to a server:
28
+
29
+ require 'rubygems'
30
+ require 'zookeeper'
31
+ z = Zookeeper.new("localhost:2181")
32
+ z.get_children(:path => "/")
33
+
34
+ ## Idioms
35
+
36
+ The following methods are initially supported:
37
+ * get
38
+ * set
39
+ * get\_children
40
+ * stat
41
+ * create
42
+ * delete
43
+ * get\_acl
44
+ * set\_acl
45
+
46
+ All support async callbacks. get, get\_children and stat support both watchers and callbacks.
47
+
48
+ Calls take a dictionary of parameters. With the exception of set\_acl, the only required parameter is :path. Each call returns a dictionary with at minimum two keys :req\_id and :rc.
49
+
50
+ ### A Bit about this repository ###
51
+
52
+ Twitter's open source office was kind enough to transfer this repository to facilitate development and administration of this repository. The `zookeeper` gem's last three releases were recorded in branches `v0.4.2`, `v0.4.3` and `v0.4.4`. Releases of the `slyphon-zookeeper` gem were cut off of the fork, and unfortunately (due to an oversight on my part) were tagged with unrelated versions. Those were tagged with names `release/0.9.2`.
53
+
54
+ The plan is to keep the `slyphon-zookeeper` tags, and to tag the `zookeeper` releases `twitter/release/0.4.x`.
55
+
56
+ Further work will be carried out on this repository. The `0.9.3` release of the zookeeper gem will be released under the 'zookeeper' name, and will bring the two divergent (conceptual) branches of development together.
57
+
58
+
59
+
data/Rakefile CHANGED
@@ -1,9 +1,139 @@
1
- require 'echoe'
1
+ # def gemset_name
2
+ # ENV.fetch('GEM_HOME').split('@').last
3
+ # end
2
4
 
3
- Echoe.new("zookeeper") do |p|
4
- p.author = "Phillip Pearson, Eric Maland, Evan Weaver, Brian Wickman"
5
- p.project = "twitter"
6
- p.summary = "An interface to the Zookeeper distributed configuration server."
7
- p.clean_pattern += ["ext/lib", "ext/include", "ext/c", "ext/bin", "ext/conftest.dSYM"]
8
- p.rdoc_pattern = /README|TODO|LICENSE|CHANGELOG|BENCH|COMPAT|zookeeper_c.c|zookeeper.rb/
5
+ GEM_FILES = FileList['slyphon-zookeeper-*.gem']
6
+
7
+ namespace :mb do
8
+ namespace :gems do
9
+ task :build do
10
+ sh "rvm 1.8.7 do gem build zookeeper.gemspec"
11
+ ENV['JAVA_GEM'] = '1'
12
+ sh "rvm 1.8.7 do gem build zookeeper.gemspec"
13
+ end
14
+
15
+ task :push do
16
+ GEM_FILES.each do |gem|
17
+ sh "gem push #{gem}"
18
+ end
19
+ end
20
+
21
+ task :clean do
22
+ rm_rf GEM_FILES
23
+ end
24
+
25
+ task :all => [:build, :push, :clean]
26
+ end
9
27
  end
28
+
29
+ gemset_name = 'zookeeper'
30
+
31
+ # this nonsense w/ tmp and the Gemfile is a bundler optimization
32
+
33
+ %w[1.8.7 1.9.2 jruby rbx 1.9.3].each do |ns_name|
34
+ rvm_ruby = (ns_name == 'rbx') ? "rbx-2.0.testing" : ns_name
35
+
36
+ ruby_with_gemset = "#{rvm_ruby}@#{gemset_name}"
37
+
38
+ create_gemset_name = "mb:#{ns_name}:create_gemset"
39
+ clobber_task_name = "mb:#{ns_name}:clobber"
40
+ clean_task_name = "mb:#{ns_name}:clean"
41
+ build_task_name = "mb:#{ns_name}:build"
42
+ bundle_task_name = "mb:#{ns_name}:bundle_install"
43
+ rspec_task_name = "mb:#{ns_name}:run_rspec"
44
+
45
+ phony_gemfile_link_name = "Gemfile.#{ns_name}"
46
+ phony_gemfile_lock_name = "#{phony_gemfile_link_name}.lock"
47
+
48
+ file phony_gemfile_link_name do
49
+ # apparently, rake doesn't deal with symlinks intelligently :P
50
+ ln_s('Gemfile', phony_gemfile_link_name) unless File.symlink?(phony_gemfile_link_name)
51
+ end
52
+
53
+ task :clean do
54
+ rm_rf [phony_gemfile_lock_name, phony_gemfile_lock_name]
55
+ end
56
+
57
+ task create_gemset_name do
58
+ sh "rvm #{rvm_ruby} do rvm gemset create #{gemset_name}"
59
+ end
60
+
61
+ task clobber_task_name do
62
+ unless rvm_ruby == 'jruby'
63
+ cd 'ext' do
64
+ sh "rake clobber"
65
+ end
66
+ end
67
+ end
68
+
69
+ task clean_task_name do
70
+ unless rvm_ruby == 'jruby'
71
+ cd 'ext' do
72
+ sh "rake clean"
73
+ end
74
+ end
75
+ end
76
+
77
+ task build_task_name => [create_gemset_name, clean_task_name] do
78
+ unless rvm_ruby == 'jruby'
79
+ cd 'ext' do
80
+ sh "rvm #{ruby_with_gemset} do rake build"
81
+ end
82
+ end
83
+ end
84
+
85
+ task bundle_task_name => [phony_gemfile_link_name, build_task_name] do
86
+ sh "rvm #{ruby_with_gemset} do bundle install --gemfile #{phony_gemfile_link_name}"
87
+ end
88
+
89
+ task rspec_task_name => bundle_task_name do
90
+ sh "rvm #{ruby_with_gemset} do env BUNDLE_GEMFILE=#{phony_gemfile_link_name} bundle exec rspec spec --fail-fast"
91
+ end
92
+
93
+ task "mb:#{ns_name}" => rspec_task_name
94
+
95
+ task "mb:test_all_rubies" => rspec_task_name
96
+ end
97
+
98
+ task "mb:test_all" do
99
+ require 'benchmark'
100
+ t = Benchmark.realtime do
101
+ Rake::Task['mb:test_all_rubies'].invoke
102
+ end
103
+
104
+ $stderr.puts "Test run took: #{t} s"
105
+ end
106
+
107
+ task :default => 'mb:1.9.3'
108
+
109
+ task :clobber do
110
+ rm_rf 'tmp'
111
+ end
112
+
113
+ # cargo culted from http://blog.flavorjon.es/2009/06/easily-valgrind-gdb-your-ruby-c.html
114
+ VALGRIND_BASIC_OPTS = '--num-callers=50 --error-limit=no --partial-loads-ok=yes --undef-value-errors=no'
115
+
116
+ task 'valgrind' do
117
+ cd 'ext' do
118
+ sh "rake clean build"
119
+ end
120
+
121
+ sh "valgrind #{VALGRIND_BASIC_OPTS} bundle exec rspec spec"
122
+ end
123
+
124
+ namespace :build do
125
+ task :clean do
126
+ cd 'ext' do
127
+ sh 'rake clean'
128
+ end
129
+
130
+ Rake::Task['build'].invoke
131
+ end
132
+ end
133
+
134
+ task :build do
135
+ cd 'ext' do
136
+ sh "rake"
137
+ end
138
+ end
139
+
data/ext/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ bin
2
+ include
3
+ lib
4
+ *.bundle
5
+
6
+ c
data/ext/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+
2
+ task :clean do
3
+ if File.exists?('Makefile')
4
+ sh 'make clean'
5
+ else
6
+ $stderr.puts "nothing to clean, no Makefile"
7
+ end
8
+ end
9
+
10
+ GENERATE_GVL_CODE_RB = 'generate_gvl_code.rb'
11
+
12
+ file 'c' do
13
+ if tarball = Dir['zkc-*.tar.gz'].first
14
+ sh "tar -zxf #{tarball}"
15
+ else
16
+ raise "couldn't find the tarball! wtf?!"
17
+ end
18
+ end
19
+
20
+ file GENERATE_GVL_CODE_RB => 'c'
21
+
22
+ file 'zkrb_wrapper.c' => GENERATE_GVL_CODE_RB do
23
+ sh "ruby generate_gvl_code.rb code"
24
+ end
25
+
26
+ file 'zkrb_wrapper.h' => GENERATE_GVL_CODE_RB do
27
+ sh "ruby generate_gvl_code.rb headers"
28
+ end
29
+
30
+ ZKRB_WRAPPER = %w[zkrb_wrapper.c zkrb_wrapper.h]
31
+
32
+
33
+ task :wrappers => ZKRB_WRAPPER
34
+
35
+
36
+ task :clobber => :clean do
37
+ rm_rf %w[Makefile c lib bin include]
38
+ end
39
+
40
+ task :build_zkc do
41
+ sh 'ruby extconf.rb'
42
+ end
43
+
44
+ file 'Makefile' => :build_zkc
45
+
46
+ task :build => [ZKRB_WRAPPER, 'Makefile'].flatten do
47
+ sh 'make'
48
+ end
49
+
50
+ task :default => :build
51
+
@@ -0,0 +1,212 @@
1
+ require 'zookeeper/constants'
2
+ require File.expand_path('../zookeeper_c', __FILE__)
3
+
4
+ # TODO: see if we can get the destructor to handle thread/event queue teardown
5
+ # when we're garbage collected
6
+ class CZookeeper
7
+ include ZookeeperCommon
8
+ include ZookeeperConstants
9
+ include ZookeeperExceptions
10
+
11
+ DEFAULT_SESSION_TIMEOUT_MSEC = 10000
12
+
13
+ class GotNilEventException < StandardError; end
14
+
15
+ # assume we're at debug level
16
+ def self.get_debug_level
17
+ @debug_level ||= ZOO_LOG_LEVEL_INFO
18
+ end
19
+
20
+ def self.set_debug_level(value)
21
+ @debug_level = value
22
+ set_zkrb_debug_level(value)
23
+ end
24
+
25
+ def initialize(host, event_queue, opts={})
26
+ @host = host
27
+ @event_queue = event_queue
28
+
29
+ # used by the C layer. CZookeeper sets this to true when the init method
30
+ # has completed. once this is set to true, it stays true.
31
+ #
32
+ # you should grab the @start_stop_mutex before messing with this flag
33
+ @_running = nil
34
+
35
+ # This is set to true after destroy_zkrb_instance has been called and all
36
+ # CZookeeper state has been cleaned up
37
+ @_closed = false # also used by the C layer
38
+
39
+ # set by the ruby side to indicate we are in shutdown mode used by method_get_next_event
40
+ @_shutting_down = false
41
+
42
+ # the actual C data is stashed in this ivar. never *ever* touch this
43
+ @_data = nil
44
+
45
+ @_session_timeout_msec = DEFAULT_SESSION_TIMEOUT_MSEC
46
+
47
+ @start_stop_mutex = Monitor.new
48
+
49
+ # used to signal that we're running
50
+ @running_cond = @start_stop_mutex.new_cond
51
+
52
+ @event_thread = nil
53
+
54
+ setup_event_thread!
55
+
56
+ zkrb_init(@host)
57
+
58
+ logger.debug { "init returned!" }
59
+ end
60
+
61
+ def closed?
62
+ @start_stop_mutex.synchronize { !!@_closed }
63
+ end
64
+
65
+ def running?
66
+ @start_stop_mutex.synchronize { !!@_running }
67
+ end
68
+
69
+ def shutting_down?
70
+ @start_stop_mutex.synchronize { !!@_shutting_down }
71
+ end
72
+
73
+ def connected?
74
+ state == ZOO_CONNECTED_STATE
75
+ end
76
+
77
+ def connecting?
78
+ state == ZOO_CONNECTING_STATE
79
+ end
80
+
81
+ def associating?
82
+ state == ZOO_ASSOCIATING_STATE
83
+ end
84
+
85
+ def close
86
+ return if closed?
87
+
88
+ shut_down!
89
+ stop_event_thread!
90
+
91
+ @start_stop_mutex.synchronize do
92
+ if !@_closed and @_data
93
+ close_handle
94
+ end
95
+ end
96
+
97
+ nil
98
+ end
99
+
100
+ def state
101
+ return ZOO_CLOSED_STATE if closed?
102
+ zkrb_state
103
+ end
104
+
105
+ # this implementation is gross, but i don't really see another way of doing it
106
+ # without more grossness
107
+ #
108
+ # returns true if we're connected, false if we're not
109
+ #
110
+ # if timeout is nil, we never time out, and wait forever for CONNECTED state
111
+ #
112
+ def wait_until_connected(timeout=10)
113
+ return false unless wait_until_running(timeout)
114
+
115
+ time_to_stop = timeout ? (Time.now + timeout) : nil
116
+
117
+ until connected? or (time_to_stop and Time.now > time_to_stop)
118
+ Thread.pass
119
+ end
120
+
121
+ connected?
122
+ end
123
+
124
+ private
125
+ # will wait until the client has entered the running? state
126
+ # or until timeout seconds have passed.
127
+ #
128
+ # returns true if we're running, false if we timed out
129
+ def wait_until_running(timeout=5)
130
+ @start_stop_mutex.synchronize do
131
+ return true if @_running
132
+ @running_cond.wait(timeout)
133
+ !!@_running
134
+ end
135
+ end
136
+
137
+ def setup_event_thread!
138
+ @event_thread ||= Thread.new(&method(:_event_thread_body))
139
+ end
140
+
141
+ def _event_thread_body
142
+ logger.debug { "event_thread waiting until running: #{@_running}" }
143
+
144
+ @start_stop_mutex.synchronize do
145
+ @running_cond.wait_until { @_running }
146
+
147
+ if @_shutting_down
148
+ logger.error { "event thread saw @_shutting_down, bailing without entering loop" }
149
+ return
150
+ end
151
+ end
152
+
153
+ logger.debug { "event_thread running: #{@_running}" }
154
+
155
+ while true
156
+ begin
157
+ _iterate_event_delivery
158
+ rescue GotNilEventException
159
+ logger.debug { "#{self.class}##{__method__}: event delivery thread is exiting" }
160
+ break
161
+ end
162
+ end
163
+ end
164
+
165
+ def _iterate_event_delivery
166
+ get_next_event(true).tap do |hash|
167
+ raise GotNilEventException if hash.nil?
168
+ @event_queue.push(hash)
169
+ end
170
+ end
171
+
172
+ # use this method to set the @_shutting_down flag to true
173
+ def shut_down!
174
+ logger.debug { "#{self.class}##{__method__}" }
175
+
176
+ @start_stop_mutex.synchronize do
177
+ @_shutting_down = true
178
+ end
179
+ end
180
+
181
+ # this method is part of the reopen/close code, and is responsible for
182
+ # shutting down the dispatch thread.
183
+ #
184
+ # @dispatch will be nil when this method exits
185
+ #
186
+ def stop_event_thread!
187
+ logger.debug { "#{self.class}##{__method__}" }
188
+
189
+ if @event_thread
190
+ unless @_closed
191
+ wake_event_loop! # this is a C method
192
+ end
193
+ @event_thread.join
194
+ @event_thread = nil
195
+ end
196
+ end
197
+
198
+ def logger
199
+ Zookeeper.logger
200
+ end
201
+
202
+ # called by underlying C code to signal we're running
203
+ def zkc_set_running_and_notify!
204
+ logger.debug { "#{self.class}##{__method__}" }
205
+
206
+ @start_stop_mutex.synchronize do
207
+ @_running = true
208
+ @running_cond.broadcast
209
+ end
210
+ end
211
+ end
212
+
data/ext/dbg.h ADDED
@@ -0,0 +1,53 @@
1
+ #ifndef __dbg_h__
2
+ #define __dbg_h__
3
+
4
+ // ALL GLORY TO THE Zed A. Shaw
5
+ // http://c.learncodethehardway.org/book/learn-c-the-hard-waych21.html#x26-10500021
6
+
7
+ #include <stdio.h>
8
+ #include <errno.h>
9
+ #include <string.h>
10
+
11
+ #ifdef NDEBUG
12
+ #define debug(M, ...)
13
+ #else
14
+ #define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
15
+ #endif
16
+
17
+ #define clean_errno() (errno == 0 ? "None" : strerror(errno))
18
+
19
+ #define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
20
+
21
+ #define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
22
+
23
+ #define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
24
+
25
+ // acts to assert that A is true
26
+ #define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
27
+
28
+ // like check, but provide an explicit goto label name
29
+ #define check_goto(A, L, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto L; }
30
+
31
+ // like check, but implicit jump to 'unlock' label
32
+ #define check_unlock(A, M, ...) check_goto(A, unlock, M, ##__VA_ARGS__)
33
+
34
+ #define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
35
+
36
+ #define check_mem(A) check((A), "Out of memory.")
37
+
38
+ // checks the condition A, if not true, logs the message M given using zkrb_debug
39
+ // then does a goto to the label L
40
+ #define check_debug_goto(A, L, M, ...) if(!(A)) { zkrb_debug(M, ##__VA_ARGS__); errno=0; goto L; }
41
+
42
+ // check_debug_goto with implicit 'unlock' label
43
+ #define check_debug_unlock(A, M, ...) check_debug_goto(A, unlock, M, ##__VA_ARGS__)
44
+
45
+ // like check_debug_goto, but the label is implicitly 'error'
46
+ #define check_debug(A, M, ...) check_debug_goto(A, error, M, ##__VA_ARGS__)
47
+
48
+ #define zkrb_debug(M, ...) if (ZKRBDebugging) fprintf(stderr, "DEBUG %p:%s:%d: " M "\n", pthread_self(), __FILE__, __LINE__, ##__VA_ARGS__)
49
+ #define zkrb_debug_inst(O, M, ...) zkrb_debug("obj_id: %lx, " M, FIX2LONG(rb_obj_id(O)), ##__VA_ARGS__)
50
+
51
+ // __dbg_h__
52
+ #endif
53
+
data/ext/depend ADDED
@@ -0,0 +1,5 @@
1
+ zookeeper_lib.c: zookeeper_lib.h
2
+ zkrb_wrapper_compat.c: zkrb_wrapper_compat.h
3
+ zkrb_wrapper.c: zkrb_wrapper_compat.c zkrb_wrapper.h
4
+ zookeeper_c.c: zookeeper_lib.c zookeeper_lib.h zkrb_wrapper.c zkrb_wrapper.h dbg.h
5
+