zookeeper-ng 1.5.2.1-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.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.ctags_paths +1 -0
  3. data/.dotfiles/ruby-gemset +1 -0
  4. data/.dotfiles/ruby-version +1 -0
  5. data/.dotfiles/rvmrc +2 -0
  6. data/.github/workflows/build.yml +57 -0
  7. data/.gitignore +19 -0
  8. data/.gitmodules +3 -0
  9. data/CHANGELOG +408 -0
  10. data/Gemfile +30 -0
  11. data/Guardfile +8 -0
  12. data/LICENSE +23 -0
  13. data/Manifest +29 -0
  14. data/README.markdown +62 -0
  15. data/Rakefile +121 -0
  16. data/cause-abort.rb +117 -0
  17. data/ext/.gitignore +6 -0
  18. data/ext/Rakefile +41 -0
  19. data/ext/c_zookeeper.rb +398 -0
  20. data/ext/common.h +17 -0
  21. data/ext/dbg.h +53 -0
  22. data/ext/depend +5 -0
  23. data/ext/event_lib.c +740 -0
  24. data/ext/event_lib.h +175 -0
  25. data/ext/extconf.rb +103 -0
  26. data/ext/generate_gvl_code.rb +321 -0
  27. data/ext/patches/zkc-3.3.5-network.patch +24 -0
  28. data/ext/patches/zkc-3.4.5-buffer-overflow.patch +11 -0
  29. data/ext/patches/zkc-3.4.5-config.patch +5454 -0
  30. data/ext/patches/zkc-3.4.5-fetch-and-add.patch +16 -0
  31. data/ext/patches/zkc-3.4.5-logging.patch +41 -0
  32. data/ext/patches/zkc-3.4.5-out-of-order-ping.patch +163 -0
  33. data/ext/patches/zkc-3.4.5-yosemite-htonl-fix.patch +102 -0
  34. data/ext/zkc-3.4.5.tar.gz +0 -0
  35. data/ext/zkrb.c +1080 -0
  36. data/ext/zkrb_wrapper.c +775 -0
  37. data/ext/zkrb_wrapper.h +350 -0
  38. data/ext/zkrb_wrapper_compat.c +15 -0
  39. data/ext/zkrb_wrapper_compat.h +11 -0
  40. data/ext/zookeeper_base.rb +256 -0
  41. data/java/java_base.rb +501 -0
  42. data/lib/zookeeper/acls.rb +44 -0
  43. data/lib/zookeeper/callbacks.rb +108 -0
  44. data/lib/zookeeper/client.rb +30 -0
  45. data/lib/zookeeper/client_methods.rb +282 -0
  46. data/lib/zookeeper/common/queue_with_pipe.rb +110 -0
  47. data/lib/zookeeper/common.rb +122 -0
  48. data/lib/zookeeper/compatibility.rb +138 -0
  49. data/lib/zookeeper/constants.rb +97 -0
  50. data/lib/zookeeper/continuation.rb +223 -0
  51. data/lib/zookeeper/core_ext.rb +58 -0
  52. data/lib/zookeeper/em_client.rb +55 -0
  53. data/lib/zookeeper/exceptions.rb +135 -0
  54. data/lib/zookeeper/forked.rb +19 -0
  55. data/lib/zookeeper/latch.rb +34 -0
  56. data/lib/zookeeper/logger/forwarding_logger.rb +84 -0
  57. data/lib/zookeeper/logger.rb +39 -0
  58. data/lib/zookeeper/monitor.rb +19 -0
  59. data/lib/zookeeper/rake_tasks.rb +165 -0
  60. data/lib/zookeeper/request_registry.rb +153 -0
  61. data/lib/zookeeper/stat.rb +21 -0
  62. data/lib/zookeeper/version.rb +4 -0
  63. data/lib/zookeeper.rb +115 -0
  64. data/notes.txt +14 -0
  65. data/scripts/upgrade-1.0-sed-alike.rb +46 -0
  66. data/spec/c_zookeeper_spec.rb +51 -0
  67. data/spec/chrooted_connection_spec.rb +83 -0
  68. data/spec/compatibilty_spec.rb +8 -0
  69. data/spec/default_watcher_spec.rb +41 -0
  70. data/spec/em_spec.rb +51 -0
  71. data/spec/ext/zookeeper_base_spec.rb +19 -0
  72. data/spec/forked_connection_spec.rb +122 -0
  73. data/spec/latch_spec.rb +24 -0
  74. data/spec/log4j.properties +17 -0
  75. data/spec/shared/all_success_return_values.rb +10 -0
  76. data/spec/shared/connection_examples.rb +1081 -0
  77. data/spec/spec_helper.rb +61 -0
  78. data/spec/support/00_logging.rb +38 -0
  79. data/spec/support/10_spawn_zookeeper.rb +20 -0
  80. data/spec/support/progress_formatter.rb +15 -0
  81. data/spec/support/zookeeper_spec_helpers.rb +96 -0
  82. data/spec/zookeeper_spec.rb +24 -0
  83. data/zookeeper.gemspec +46 -0
  84. data/zoomonkey/duplicates +3 -0
  85. data/zoomonkey/zoomonkey.rb +194 -0
  86. metadata +185 -0
@@ -0,0 +1,282 @@
1
+ module Zookeeper
2
+ module ClientMethods
3
+ extend Forwardable
4
+ include Constants
5
+ include ACLs
6
+ include Logger
7
+
8
+ # @req_registry is set up in the platform-specific base classes
9
+ def_delegators :@req_registry, :setup_call
10
+ private :setup_call
11
+
12
+ def reopen(timeout=10, watcher=nil, opts = {})
13
+ warn "WARN: ZookeeperBase#reopen watcher argument is now ignored" if watcher
14
+ super
15
+ end
16
+
17
+ def initialize(host, timeout=10, watcher=nil, opts = {})
18
+ super
19
+ end
20
+
21
+ def add_auth(options = {})
22
+ assert_open
23
+ assert_keys(options,
24
+ :supported => [:scheme, :cert],
25
+ :required => [:scheme, :cert])
26
+
27
+ req_id = setup_call(:add_auth, options)
28
+ rc = super(req_id, options[:scheme], options[:cert])
29
+
30
+ { :req_id => req_id, :rc => rc }
31
+ end
32
+
33
+ def get(options = {})
34
+ assert_open
35
+ assert_keys(options,
36
+ :supported => [:path, :watcher, :watcher_context, :callback, :callback_context],
37
+ :required => [:path])
38
+
39
+ req_id = setup_call(:get, options)
40
+ rc, value, stat = super(req_id, options[:path], options[:callback], options[:watcher])
41
+
42
+ rv = { :req_id => req_id, :rc => rc }
43
+ options[:callback] ? rv : rv.merge(:data => value, :stat => Stat.new(stat))
44
+ end
45
+
46
+ def set(options = {})
47
+ assert_open
48
+ assert_keys(options,
49
+ :supported => [:path, :data, :version, :callback, :callback_context],
50
+ :required => [:path])
51
+
52
+ assert_valid_data_size!(options[:data])
53
+ options[:version] ||= -1
54
+
55
+ req_id = setup_call(:set, options)
56
+ rc, stat = super(req_id, options[:path], options[:data], options[:callback], options[:version])
57
+
58
+ rv = { :req_id => req_id, :rc => rc }
59
+ options[:callback] ? rv : rv.merge(:stat => Stat.new(stat))
60
+ end
61
+
62
+ def get_children(options = {})
63
+ assert_open
64
+ assert_keys(options,
65
+ :supported => [:path, :callback, :callback_context, :watcher, :watcher_context],
66
+ :required => [:path])
67
+
68
+ req_id = setup_call(:get_children, options)
69
+ rc, children, stat = super(req_id, options[:path], options[:callback], options[:watcher])
70
+
71
+ rv = { :req_id => req_id, :rc => rc }
72
+ options[:callback] ? rv : rv.merge(:children => children, :stat => Stat.new(stat))
73
+ end
74
+
75
+ def stat(options = {})
76
+ assert_open
77
+ assert_keys(options,
78
+ :supported => [:path, :callback, :callback_context, :watcher, :watcher_context],
79
+ :required => [:path])
80
+
81
+ req_id = setup_call(:stat, options)
82
+ rc, stat = exists(req_id, options[:path], options[:callback], options[:watcher])
83
+
84
+ rv = { :req_id => req_id, :rc => rc }
85
+ options[:callback] ? rv : rv.merge(:stat => Stat.new(stat))
86
+ end
87
+
88
+ def create(options = {})
89
+ assert_open
90
+ assert_keys(options,
91
+ :supported => [:path, :data, :acl, :ephemeral, :sequence, :callback, :callback_context],
92
+ :required => [:path])
93
+
94
+ assert_valid_data_size!(options[:data])
95
+
96
+ flags = 0
97
+ flags |= ZOO_EPHEMERAL if options[:ephemeral]
98
+ flags |= ZOO_SEQUENCE if options[:sequence]
99
+
100
+ options[:acl] ||= ZOO_OPEN_ACL_UNSAFE
101
+
102
+ req_id = setup_call(:create, options)
103
+ rc, newpath = super(req_id, options[:path], options[:data], options[:callback], options[:acl], flags)
104
+
105
+ rv = { :req_id => req_id, :rc => rc }
106
+ options[:callback] ? rv : rv.merge(:path => newpath)
107
+ end
108
+
109
+ def delete(options = {})
110
+ assert_open
111
+ assert_keys(options,
112
+ :supported => [:path, :version, :callback, :callback_context],
113
+ :required => [:path])
114
+
115
+ options[:version] ||= -1
116
+
117
+ req_id = setup_call(:delete, options)
118
+ rc = super(req_id, options[:path], options[:version], options[:callback])
119
+
120
+ { :req_id => req_id, :rc => rc }
121
+ end
122
+
123
+ # this method is *only* asynchronous
124
+ #
125
+ # @note There is a discrepancy between the zkc and java versions. zkc takes
126
+ # a string_callback_t, java takes a VoidCallback. You should most likely use
127
+ # the Zookeeper::Callbacks::VoidCallback and not rely on the string value.
128
+ #
129
+ def sync(options = {})
130
+ assert_open
131
+ assert_keys(options,
132
+ :supported => [:path, :callback, :callback_context],
133
+ :required => [:path, :callback])
134
+
135
+ req_id = setup_call(:sync, options)
136
+
137
+ rc = super(req_id, options[:path]) # we don't pass options[:callback] here as this method is *always* async
138
+
139
+ { :req_id => req_id, :rc => rc }
140
+ end
141
+
142
+ def set_acl(options = {})
143
+ assert_open
144
+ assert_keys(options,
145
+ :supported => [:path, :acl, :version, :callback, :callback_context],
146
+ :required => [:path, :acl])
147
+ options[:version] ||= -1
148
+
149
+ req_id = setup_call(:set_acl, options)
150
+ rc = super(req_id, options[:path], options[:acl], options[:callback], options[:version])
151
+
152
+ { :req_id => req_id, :rc => rc }
153
+ end
154
+
155
+ def get_acl(options = {})
156
+ assert_open
157
+ assert_keys(options,
158
+ :supported => [:path, :callback, :callback_context],
159
+ :required => [:path])
160
+
161
+ req_id = setup_call(:get_acl, options)
162
+ rc, acls, stat = super(req_id, options[:path], options[:callback])
163
+
164
+ rv = { :req_id => req_id, :rc => rc }
165
+ options[:callback] ? rv : rv.merge(:acl => acls, :stat => Stat.new(stat))
166
+ end
167
+
168
+ # close this client and any underlying connections
169
+ def close
170
+ super
171
+ end
172
+
173
+ def state
174
+ super
175
+ end
176
+
177
+ def connected?
178
+ super
179
+ end
180
+
181
+ def connecting?
182
+ super
183
+ end
184
+
185
+ def associating?
186
+ super
187
+ end
188
+
189
+ # There are some operations that are dangerous in the context of the event
190
+ # dispatch thread (because they would block further event delivery). This
191
+ # method allows clients to know if they're currently executing in the context of an
192
+ # event.
193
+ #
194
+ # @returns [true,false] true if the current thread is the event dispatch thread
195
+ def event_dispatch_thread?
196
+ super
197
+ end
198
+
199
+ # DEPRECATED: use the class-level method instead
200
+ def set_debug_level(val)
201
+ super
202
+ end
203
+
204
+ # has the underlying connection been closed?
205
+ def closed?
206
+ super
207
+ end
208
+
209
+ # is the event delivery system running?
210
+ def running?
211
+ super
212
+ end
213
+
214
+ # return the session id of the current connection as an Fixnum
215
+ def session_id
216
+ super
217
+ end
218
+
219
+ # Return the passwd portion of this connection's credentials as a String
220
+ def session_passwd
221
+ super
222
+ end
223
+
224
+ # stop all underlying threads in preparation for a fork()
225
+ def pause_before_fork_in_parent
226
+ super
227
+ end
228
+
229
+ # re-start all underlying threads after performing a fork()
230
+ def resume_after_fork_in_parent
231
+ super
232
+ end
233
+
234
+ protected
235
+ # used during shutdown, awaken the event delivery thread if it's blocked
236
+ # waiting for the next event
237
+ def wake_event_loop!
238
+ super
239
+ end
240
+
241
+ # starts the event delivery subsystem going. after calling this method, running? will be true
242
+ def setup_dispatch_thread!
243
+ super
244
+ end
245
+
246
+ # TODO: describe what this does
247
+ def get_default_global_watcher
248
+ super
249
+ end
250
+
251
+ def assert_valid_data_size!(data)
252
+ return if data.nil?
253
+
254
+ data = data.to_s
255
+ if data.length >= 1048576 # one megabyte
256
+ raise Zookeeper::Exceptions::DataTooLargeException, "data must be smaller than 1 MiB, your data starts with: #{data[0..32].inspect}"
257
+ end
258
+ nil
259
+ end
260
+
261
+ private
262
+ def assert_keys(args, opts={})
263
+ supported = opts[:supported] || []
264
+ required = opts[:required] || []
265
+
266
+ unless (args.keys - supported).empty?
267
+ raise Zookeeper::Exceptions::BadArguments,
268
+ "Supported arguments are: #{supported.inspect}, but arguments #{args.keys.inspect} were supplied instead"
269
+ end
270
+
271
+ unless (required - args.keys).empty?
272
+ raise Zookeeper::Exceptions::BadArguments,
273
+ "Required arguments are: #{required.inspect}, but only the arguments #{args.keys.inspect} were supplied."
274
+ end
275
+ end
276
+
277
+ # must be supplied by parent class impl.
278
+ def assert_open
279
+ super
280
+ end
281
+ end # ClientMethods
282
+ end # Zookeeper
@@ -0,0 +1,110 @@
1
+ module Zookeeper
2
+ module Common
3
+ # Ceci n'est pas une pipe
4
+ class QueueWithPipe
5
+ extend Forwardable
6
+ include Logger
7
+
8
+ # raised when close has been called, and pop() is performed
9
+ #
10
+ class ShutdownException < StandardError; end
11
+
12
+ # @private
13
+ KILL_TOKEN = Object.new unless defined?(KILL_TOKEN)
14
+
15
+ def initialize
16
+ @array = []
17
+
18
+ @mutex = Mutex.new
19
+ @cond = ConditionVariable.new
20
+ @closed = false
21
+ @graceful = false
22
+ end
23
+
24
+ def clear
25
+ @mutex.lock
26
+ begin
27
+ @array.clear
28
+ ensure
29
+ @mutex.unlock rescue nil
30
+ end
31
+ end
32
+
33
+ def push(obj)
34
+ @mutex.lock
35
+ begin
36
+ # raise ShutdownException if (@closed or @graceful)
37
+ @array << obj
38
+ @cond.signal
39
+ ensure
40
+ @mutex.unlock rescue nil
41
+ end
42
+ end
43
+
44
+ def pop(non_blocking=false)
45
+ rval = nil
46
+
47
+ @mutex.lock
48
+ begin
49
+
50
+ begin
51
+ raise ShutdownException if @closed # this may get us in trouble
52
+
53
+ rval = @array.shift
54
+
55
+ unless rval
56
+ raise ThreadError if non_blocking # sigh, ruby's stupid behavior
57
+ raise ShutdownException if @graceful # we've processed all the remaining mesages
58
+
59
+ @cond.wait(@mutex) until (@closed or @graceful or (@array.length > 0))
60
+ end
61
+ end until rval
62
+
63
+ return rval
64
+
65
+ ensure
66
+ @mutex.unlock rescue nil
67
+ end
68
+ end
69
+
70
+ # close the queue and causes ShutdownException to be raised on waiting threads
71
+ def graceful_close!
72
+ @mutex.lock
73
+ begin
74
+ return if @graceful or @closed
75
+ logger.debug { "#{self.class}##{__method__} gracefully closing" }
76
+ @graceful = true
77
+ @cond.broadcast
78
+ ensure
79
+ @mutex.unlock rescue nil
80
+ end
81
+ nil
82
+ end
83
+
84
+ def open
85
+ @mutex.lock
86
+ begin
87
+ @closed = @graceful = false
88
+ @cond.broadcast
89
+ ensure
90
+ @mutex.unlock rescue nil
91
+ end
92
+ end
93
+
94
+ def close
95
+ @mutex.lock
96
+ begin
97
+ return if @closed
98
+ @closed = true
99
+ @cond.broadcast
100
+ ensure
101
+ @mutex.unlock rescue nil
102
+ end
103
+ end
104
+
105
+ def closed?
106
+ @mutex.synchronize { !!@closed }
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,122 @@
1
+ require 'zookeeper/exceptions'
2
+ require 'zookeeper/common/queue_with_pipe'
3
+
4
+ module Zookeeper
5
+ module Common
6
+ def event_dispatch_thread?
7
+ @dispatcher && (@dispatcher == Thread.current)
8
+ end
9
+
10
+ private
11
+ def setup_dispatch_thread!
12
+ @mutex.synchronize do
13
+ if @dispatcher
14
+ logger.debug { "dispatcher already running" }
15
+ return
16
+ end
17
+
18
+ logger.debug { "starting dispatch thread" }
19
+
20
+ @dispatcher = Thread.new(&method(:dispatch_thread_body))
21
+ end
22
+ end
23
+
24
+ # this method is part of the reopen/close code, and is responsible for
25
+ # shutting down the dispatch thread.
26
+ #
27
+ # @dispatcher will be nil when this method exits
28
+ #
29
+ def stop_dispatch_thread!(timeout=2)
30
+ logger.debug { "#{self.class}##{__method__}" }
31
+
32
+ if @dispatcher
33
+ if @dispatcher.join(0)
34
+ @dispatcher = nil
35
+ return
36
+ end
37
+
38
+ @mutex.synchronize do
39
+ event_queue.graceful_close!
40
+
41
+ # we now release the mutex so that dispatch_next_callback can grab it
42
+ # to do what it needs to do while delivering events
43
+ #
44
+ @dispatch_shutdown_cond.wait
45
+
46
+ # wait for another timeout sec for the thread to join
47
+ until @dispatcher.join(timeout)
48
+ logger.error { "Dispatch thread did not join cleanly, waiting" }
49
+ end
50
+ @dispatcher = nil
51
+ end
52
+ end
53
+ end
54
+
55
+ def get_next_event(blocking=true)
56
+ @event_queue.pop(!blocking).tap do |event|
57
+ logger.debug { "#{self.class}##{__method__} delivering event #{event.inspect}" }
58
+ end
59
+ rescue ThreadError
60
+ nil
61
+ end
62
+
63
+ def dispatch_next_callback(hash)
64
+ return nil unless hash
65
+
66
+ logger.debug { "get_next_event returned: #{prettify_event(hash).inspect}" }
67
+
68
+ is_completion = hash.has_key?(:rc)
69
+
70
+ hash[:stat] = Zookeeper::Stat.new(hash[:stat]) if hash.has_key?(:stat)
71
+ hash[:acl] = hash[:acl].map { |acl| Zookeeper::ACLs::ACL.new(acl) } if hash[:acl]
72
+
73
+ callback_context = @req_registry.get_context_for(hash)
74
+
75
+ if callback_context
76
+ callback = is_completion ? callback_context[:callback] : callback_context[:watcher]
77
+
78
+ hash[:context] = callback_context[:context]
79
+
80
+ if callback.respond_to?(:call)
81
+ callback.call(hash)
82
+ else
83
+ # puts "dispatch_next_callback found non-callback => #{callback.inspect}"
84
+ end
85
+ else
86
+ logger.warn { "Duplicate event received (no handler for req_id #{hash[:req_id]}, event: #{hash.inspect}" }
87
+ end
88
+ true
89
+ end
90
+
91
+ def dispatch_thread_body
92
+ while true
93
+ begin
94
+ dispatch_next_callback(get_next_event(true))
95
+ rescue QueueWithPipe::ShutdownException
96
+ logger.info { "dispatch thread exiting, got shutdown exception" }
97
+ return
98
+ rescue Exception => e
99
+ $stderr.puts ["#{e.class}: #{e.message}", e.backtrace.map { |n| "\t#{n}" }.join("\n")].join("\n")
100
+ end
101
+ end
102
+ ensure
103
+ signal_dispatch_thread_exit!
104
+ end
105
+
106
+ def signal_dispatch_thread_exit!
107
+ @mutex.synchronize do
108
+ logger.debug { "dispatch thread exiting!" }
109
+ @dispatch_shutdown_cond.broadcast
110
+ end
111
+ end
112
+
113
+ def prettify_event(hash)
114
+ hash.dup.tap do |h|
115
+ # pretty up the event display
116
+ h[:type] = Zookeeper::Constants::EVENT_TYPE_NAMES.fetch(h[:type]) if h[:type]
117
+ h[:state] = Zookeeper::Constants::STATE_NAMES.fetch(h[:state]) if h[:state]
118
+ h[:req_id] = :global_session if h[:req_id] == -1
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,138 @@
1
+ module Zookeeper
2
+ # @private
3
+ def self.warn_about_compatability_once!
4
+ return if @warned_about_compatibility
5
+ @warned_about_compatibility = true
6
+
7
+ warn <<-EOS
8
+
9
+ -----------------------------------------------------------------------------
10
+
11
+ NOTICE: ZOOKEEPER BACKWARDS COMPATIBILTY EANBLED!!
12
+
13
+ THIS WILL NOT BE AUTOMATIC IN 1.1 !!
14
+
15
+ There was a major change to the organization of the Zookeeper gem between
16
+ 0.9 and 1.0, breaking backwards compatibility. To ease the transition,
17
+
18
+ #{__FILE__}
19
+
20
+ is automatically required. This will *not* be the case in 1.1.
21
+
22
+ -----------------------------------------------------------------------------
23
+ EOS
24
+ end
25
+
26
+ def self.warned_about_compatability?
27
+ !!@warned_about_compatability
28
+ end
29
+ end
30
+
31
+ # at request of @eric
32
+ #Zookeeper.warn_about_compatability_once!
33
+
34
+ module Zookeeper
35
+ module Compatibility
36
+ def clean_backtrace
37
+ caller[0..-2].reject {|n| n =~ %r%/rspec/|\(eval\)|const_missing% }.map { |n| "\t#{n}" }.join("\n")
38
+ end
39
+ end
40
+ end
41
+
42
+ module ZookeeperConstants
43
+ include Zookeeper::Constants
44
+ end
45
+
46
+ module ZookeeperCallbacks
47
+ include Zookeeper::Callbacks
48
+ Callback = Base
49
+ end
50
+
51
+ module ZookeeperExceptions
52
+ include Zookeeper::Exceptions
53
+ end
54
+
55
+ module ZookeeperStat
56
+ extend Zookeeper::Compatibility
57
+ def self.const_missing(sym)
58
+ if sym == :Stat
59
+ warn "\nZookeeperStat::Stat is now Zookeeper::Stat, please update your code!\n#{clean_backtrace}"
60
+ # self.const_set(sym, Zookeeper::Stat)
61
+ Zookeeper::Stat
62
+ else
63
+ super
64
+ end
65
+ end
66
+ end
67
+
68
+ module ZookeeperACLs
69
+ extend Zookeeper::Compatibility
70
+ def self.const_missing(sym)
71
+ candidates = [Zookeeper::ACLs, Zookeeper::Constants, Zookeeper::ACLs::Constants]
72
+
73
+ candidates.each do |candidate|
74
+ if candidate.const_defined?(sym)
75
+ warn "\n#{self.name}::#{sym} is now located in #{candidate}::#{sym}, please update your code!\n#{clean_backtrace}"
76
+
77
+ c = candidate.const_get(sym)
78
+ # self.const_set(sym, c)
79
+ return c
80
+ end
81
+ end
82
+
83
+ super
84
+ end
85
+ end
86
+
87
+ module ZookeeperCommon
88
+ include Zookeeper::Common
89
+ extend Zookeeper::Compatibility
90
+
91
+ def self.const_missing(sym)
92
+ candidate = Zookeeper::Common
93
+
94
+ if candidate.const_defined?(sym)
95
+ warn "\n#{self.name}::#{sym} is now located in #{candidate}::#{sym}, please update your code!\n#{clean_backtrace}"
96
+
97
+ candidate.const_get(sym).tap do |c|
98
+ # self.const_set(sym, c)
99
+ end
100
+ else
101
+ super
102
+ end
103
+ end
104
+
105
+ end
106
+
107
+ # module Zookeeper
108
+ # include ZookeeperConstants
109
+ # include ZookeeperCallbacks
110
+ # include ZookeeperExceptions
111
+ # include ZookeeperCommon
112
+ # include ZookeeperStat
113
+ # include ZookeeperACLs
114
+ # end
115
+
116
+ module Zookeeper
117
+ extend Zookeeper::Compatibility
118
+ def self.const_missing(sym)
119
+ candidate =
120
+ case sym.to_s
121
+ when /Callback/
122
+ Zookeeper::Callbacks
123
+ end
124
+
125
+ super unless candidate
126
+
127
+ if candidate.const_defined?(sym)
128
+ warn "\n#{self.name}::#{sym} is now located in #{candidate}::#{sym}, please update your code!\n#{clean_backtrace}"
129
+
130
+ candidate.const_get(sym).tap do |c|
131
+ # self.const_set(sym, c)
132
+ end
133
+ else
134
+ super
135
+ end
136
+ end
137
+ end
138
+