zookeeper 0.9.3-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 (53) hide show
  1. data/.gitignore +10 -0
  2. data/CHANGELOG +119 -0
  3. data/Gemfile +17 -0
  4. data/LICENSE +23 -0
  5. data/Manifest +29 -0
  6. data/README.markdown +59 -0
  7. data/Rakefile +139 -0
  8. data/examples/cloud_config.rb +125 -0
  9. data/ext/.gitignore +6 -0
  10. data/ext/Rakefile +51 -0
  11. data/ext/c_zookeeper.rb +212 -0
  12. data/ext/dbg.h +53 -0
  13. data/ext/depend +5 -0
  14. data/ext/extconf.rb +85 -0
  15. data/ext/generate_gvl_code.rb +316 -0
  16. data/ext/zkc-3.3.5.tar.gz +0 -0
  17. data/ext/zkrb_wrapper.c +731 -0
  18. data/ext/zkrb_wrapper.h +330 -0
  19. data/ext/zkrb_wrapper_compat.c +15 -0
  20. data/ext/zkrb_wrapper_compat.h +11 -0
  21. data/ext/zookeeper_base.rb +211 -0
  22. data/ext/zookeeper_c.c +725 -0
  23. data/ext/zookeeper_lib.c +677 -0
  24. data/ext/zookeeper_lib.h +172 -0
  25. data/java/zookeeper_base.rb +477 -0
  26. data/lib/zookeeper.rb +297 -0
  27. data/lib/zookeeper/acls.rb +40 -0
  28. data/lib/zookeeper/callbacks.rb +91 -0
  29. data/lib/zookeeper/common.rb +174 -0
  30. data/lib/zookeeper/common/queue_with_pipe.rb +78 -0
  31. data/lib/zookeeper/constants.rb +57 -0
  32. data/lib/zookeeper/em_client.rb +55 -0
  33. data/lib/zookeeper/exceptions.rb +100 -0
  34. data/lib/zookeeper/stat.rb +21 -0
  35. data/lib/zookeeper/version.rb +6 -0
  36. data/notes.txt +14 -0
  37. data/spec/c_zookeeper_spec.rb +50 -0
  38. data/spec/chrooted_connection_spec.rb +81 -0
  39. data/spec/default_watcher_spec.rb +41 -0
  40. data/spec/em_spec.rb +51 -0
  41. data/spec/log4j.properties +17 -0
  42. data/spec/shared/all_success_return_values.rb +10 -0
  43. data/spec/shared/connection_examples.rb +1018 -0
  44. data/spec/spec_helper.rb +119 -0
  45. data/spec/support/progress_formatter.rb +15 -0
  46. data/spec/zookeeper_spec.rb +24 -0
  47. data/test/test_basic.rb +37 -0
  48. data/test/test_callback1.rb +36 -0
  49. data/test/test_close.rb +16 -0
  50. data/test/test_esoteric.rb +7 -0
  51. data/test/test_watcher1.rb +56 -0
  52. data/test/test_watcher2.rb +52 -0
  53. metadata +181 -0
data/lib/zookeeper.rb ADDED
@@ -0,0 +1,297 @@
1
+ # Ruby wrapper for the Zookeeper C API
2
+
3
+ require 'thread'
4
+ require 'monitor'
5
+ require 'forwardable'
6
+ require 'logger'
7
+
8
+ require 'zookeeper/common'
9
+ require 'zookeeper/constants'
10
+ require 'zookeeper/callbacks'
11
+ require 'zookeeper/exceptions'
12
+ require 'zookeeper/stat'
13
+ require 'zookeeper/acls'
14
+
15
+
16
+ if defined?(::JRUBY_VERSION)
17
+ $LOAD_PATH.unshift(File.expand_path('../java', File.dirname(__FILE__))).uniq!
18
+ else
19
+ $LOAD_PATH.unshift(File.expand_path('../ext', File.dirname(__FILE__))).uniq!
20
+ end
21
+
22
+ require 'zookeeper_base'
23
+
24
+ class Zookeeper < ZookeeperBase
25
+ unless defined?(@@logger)
26
+ @@logger = Logger.new($stderr).tap { |l| l.level = Logger::ERROR }
27
+ end
28
+
29
+ def self.logger
30
+ @@logger
31
+ end
32
+
33
+ def self.logger=(logger)
34
+ @@logger = logger
35
+ end
36
+
37
+ def reopen(timeout=10, watcher=nil)
38
+ warn "WARN: ZookeeperBase#reopen watcher argument is now ignored" if watcher
39
+ super
40
+ end
41
+
42
+ def initialize(host, timeout=10, watcher=nil)
43
+ super
44
+ end
45
+
46
+ def get(options = {})
47
+ assert_open
48
+ assert_supported_keys(options, [:path, :watcher, :watcher_context, :callback, :callback_context])
49
+ assert_required_keys(options, [:path])
50
+
51
+ req_id = setup_call(:get, options)
52
+ rc, value, stat = super(req_id, options[:path], options[:callback], options[:watcher])
53
+
54
+ rv = { :req_id => req_id, :rc => rc }
55
+ options[:callback] ? rv : rv.merge(:data => value, :stat => Stat.new(stat))
56
+ end
57
+
58
+ def set(options = {})
59
+ assert_open
60
+ assert_supported_keys(options, [:path, :data, :version, :callback, :callback_context])
61
+ assert_required_keys(options, [:path])
62
+ assert_valid_data_size!(options[:data])
63
+ options[:version] ||= -1
64
+
65
+ req_id = setup_call(:set, options)
66
+ rc, stat = super(req_id, options[:path], options[:data], options[:callback], options[:version])
67
+
68
+ rv = { :req_id => req_id, :rc => rc }
69
+ options[:callback] ? rv : rv.merge(:stat => Stat.new(stat))
70
+ end
71
+
72
+ def get_children(options = {})
73
+ assert_open
74
+ assert_supported_keys(options, [:path, :callback, :callback_context, :watcher, :watcher_context])
75
+ assert_required_keys(options, [:path])
76
+
77
+ req_id = setup_call(:get_children, options)
78
+ rc, children, stat = super(req_id, options[:path], options[:callback], options[:watcher])
79
+
80
+ rv = { :req_id => req_id, :rc => rc }
81
+ options[:callback] ? rv : rv.merge(:children => children, :stat => Stat.new(stat))
82
+ end
83
+
84
+ def stat(options = {})
85
+ assert_open
86
+ assert_supported_keys(options, [:path, :callback, :callback_context, :watcher, :watcher_context])
87
+ assert_required_keys(options, [:path])
88
+
89
+ req_id = setup_call(:stat, options)
90
+ rc, stat = exists(req_id, options[:path], options[:callback], options[:watcher])
91
+
92
+ rv = { :req_id => req_id, :rc => rc }
93
+ options[:callback] ? rv : rv.merge(:stat => Stat.new(stat))
94
+ end
95
+
96
+ def create(options = {})
97
+ assert_open
98
+ assert_supported_keys(options, [:path, :data, :acl, :ephemeral, :sequence, :callback, :callback_context])
99
+ assert_required_keys(options, [:path])
100
+ assert_valid_data_size!(options[:data])
101
+
102
+ flags = 0
103
+ flags |= ZOO_EPHEMERAL if options[:ephemeral]
104
+ flags |= ZOO_SEQUENCE if options[:sequence]
105
+
106
+ options[:acl] ||= ZOO_OPEN_ACL_UNSAFE
107
+
108
+ req_id = setup_call(:create, options)
109
+ rc, newpath = super(req_id, options[:path], options[:data], options[:callback], options[:acl], flags)
110
+
111
+ rv = { :req_id => req_id, :rc => rc }
112
+ options[:callback] ? rv : rv.merge(:path => newpath)
113
+ end
114
+
115
+ def delete(options = {})
116
+ assert_open
117
+ assert_supported_keys(options, [:path, :version, :callback, :callback_context])
118
+ assert_required_keys(options, [:path])
119
+ options[:version] ||= -1
120
+
121
+ req_id = setup_call(:delete, options)
122
+ rc = super(req_id, options[:path], options[:version], options[:callback])
123
+
124
+ { :req_id => req_id, :rc => rc }
125
+ end
126
+
127
+ # this method is *only* asynchronous
128
+ #
129
+ # @note There is a discrepancy between the zkc and java versions. zkc takes
130
+ # a string_callback_t, java takes a VoidCallback. You should most likely use
131
+ # the ZookeeperCallbacks::VoidCallback and not rely on the string value.
132
+ #
133
+ def sync(options = {})
134
+ assert_open
135
+ assert_supported_keys(options, [:path, :callback, :callback_context])
136
+ assert_required_keys(options, [:path, :callback])
137
+
138
+ req_id = setup_call(:sync, options)
139
+
140
+ rc = super(req_id, options[:path]) # we don't pass options[:callback] here as this method is *always* async
141
+
142
+ { :req_id => req_id, :rc => rc }
143
+ end
144
+
145
+ def set_acl(options = {})
146
+ assert_open
147
+ assert_supported_keys(options, [:path, :acl, :version, :callback, :callback_context])
148
+ assert_required_keys(options, [:path, :acl])
149
+ options[:version] ||= -1
150
+
151
+ req_id = setup_call(:set_acl, options)
152
+ rc = super(req_id, options[:path], options[:acl], options[:callback], options[:version])
153
+
154
+ { :req_id => req_id, :rc => rc }
155
+ end
156
+
157
+ def get_acl(options = {})
158
+ assert_open
159
+ assert_supported_keys(options, [:path, :callback, :callback_context])
160
+ assert_required_keys(options, [:path])
161
+
162
+ req_id = setup_call(:get_acl, options)
163
+ rc, acls, stat = super(req_id, options[:path], options[:callback])
164
+
165
+ rv = { :req_id => req_id, :rc => rc }
166
+ options[:callback] ? rv : rv.merge(:acl => acls, :stat => Stat.new(stat))
167
+ end
168
+
169
+ # close this client and any underyling connections
170
+ def close
171
+ super
172
+ end
173
+
174
+ def state
175
+ super
176
+ end
177
+
178
+ def connected?
179
+ super
180
+ end
181
+
182
+ def connecting?
183
+ super
184
+ end
185
+
186
+ def associating?
187
+ super
188
+ end
189
+
190
+ # There are some operations that are dangerous in the context of the event
191
+ # dispatch thread (because they would block further event delivery). This
192
+ # method allows clients to know if they're currently executing in the context of an
193
+ # event.
194
+ #
195
+ # @returns [true,false] true if the current thread is the event dispatch thread
196
+ def event_dispatch_thread?
197
+ super
198
+ end
199
+
200
+ # for expert use only. set the underlying debug level for the C layer, has no
201
+ # effect in java
202
+ #
203
+ # @private
204
+ def self.set_debug_level(val)
205
+ if defined?(::CZookeeper)
206
+ CZookeeper.set_debug_level(val.to_i)
207
+ end
208
+ end
209
+
210
+ # @private
211
+ def self.get_debug_level
212
+ if defined?(::CZookeeper)
213
+ CZookeeper.get_debug_level
214
+ end
215
+ end
216
+
217
+ class << self
218
+ # @private
219
+ alias :debug_level= :set_debug_level
220
+
221
+ # @private
222
+ alias :debug_level :get_debug_level
223
+ end
224
+
225
+ # DEPRECATED: use the class-level method instead
226
+ def set_debug_level(val)
227
+ super
228
+ end
229
+
230
+ # has the underlying connection been closed?
231
+ def closed?
232
+ super
233
+ end
234
+
235
+ # is the event delivery system running?
236
+ def running?
237
+ super
238
+ end
239
+
240
+ # return the session id of the current connection as an Fixnum
241
+ def session_id
242
+ super
243
+ end
244
+
245
+ # Return the passwd portion of this connection's credentials as a String
246
+ def session_passwd
247
+ super
248
+ end
249
+
250
+ protected
251
+ # used during shutdown, awaken the event delivery thread if it's blocked
252
+ # waiting for the next event
253
+ def wake_event_loop!
254
+ super
255
+ end
256
+
257
+ # starts the event delivery subsystem going. after calling this method, running? will be true
258
+ def setup_dispatch_thread!
259
+ super
260
+ end
261
+
262
+ # TODO: describe what this does
263
+ def get_default_global_watcher
264
+ super
265
+ end
266
+
267
+ def logger
268
+ Zookeeper.logger
269
+ end
270
+
271
+ def assert_valid_data_size!(data)
272
+ return if data.nil?
273
+
274
+ data = data.to_s
275
+ if data.length >= 1048576 # one megabyte
276
+ raise ZookeeperException::DataTooLargeException, "data must be smaller than 1 MiB, your data starts with: #{data[0..32].inspect}"
277
+ end
278
+ nil
279
+ end
280
+
281
+ private
282
+ # TODO: Sanitize user mistakes by unregistering watchers from ops that
283
+ # don't return ZOK (except wexists)? Make users clean up after themselves for now.
284
+ #
285
+ # XXX: is this dead code?
286
+ def unregister_watcher(req_id)
287
+ @mutex.synchronize {
288
+ @watcher_reqs.delete(req_id)
289
+ }
290
+ end
291
+
292
+ # must be supplied by parent class impl.
293
+ def assert_open
294
+ super
295
+ end
296
+ end
297
+
@@ -0,0 +1,40 @@
1
+ module ZookeeperACLs
2
+ class Id
3
+ attr_reader :scheme, :id
4
+ def initialize(hash)
5
+ @scheme = hash[:scheme]
6
+ @id = hash[:id]
7
+ end
8
+
9
+ def to_hash
10
+ { :id => id, :scheme => scheme }
11
+ end
12
+ end
13
+
14
+ class ACL
15
+ attr_reader :perms, :id
16
+ def initialize(hash)
17
+ @perms = hash[:perms]
18
+ v = hash[:id]
19
+ @id = v.kind_of?(Hash) ? Id.new(v) : v
20
+ end
21
+
22
+ def to_hash
23
+ { :perms => perms, :id => id.to_hash }
24
+ end
25
+ end
26
+
27
+ ZOO_PERM_READ = 0
28
+ ZOO_PERM_WRITE = 1
29
+ ZOO_PERM_CREATE = 2
30
+ ZOO_PERM_DELETE = 4
31
+ ZOO_PERM_ADMIN = 8
32
+ ZOO_PERM_ALL = ZOO_PERM_READ | ZOO_PERM_WRITE | ZOO_PERM_CREATE | ZOO_PERM_DELETE | ZOO_PERM_ADMIN
33
+
34
+ ZOO_ANYONE_ID_UNSAFE = Id.new(:scheme => "world", :id => "anyone")
35
+ ZOO_AUTH_IDS = Id.new(:scheme => "auth", :id => "")
36
+
37
+ ZOO_OPEN_ACL_UNSAFE = [ACL.new(:perms => ZOO_PERM_ALL, :id => ZOO_ANYONE_ID_UNSAFE)]
38
+ ZOO_READ_ACL_UNSAFE = [ACL.new(:perms => ZOO_PERM_READ, :id => ZOO_ANYONE_ID_UNSAFE)]
39
+ ZOO_CREATOR_ALL_ACL = [ACL.new(:perms => ZOO_PERM_ALL, :id => ZOO_AUTH_IDS)]
40
+ end
@@ -0,0 +1,91 @@
1
+ module ZookeeperCallbacks
2
+ class Callback
3
+ attr_reader :proc, :completed, :context
4
+
5
+ def initialize
6
+ @completed = false
7
+ @proc = Proc.new do |hash|
8
+ initialize_context(hash)
9
+ yield if block_given?
10
+ @completed = true
11
+ end
12
+ end
13
+
14
+ def call(*args)
15
+ # puts "call passed #{args.inspect}"
16
+ @proc.call(*args)
17
+ end
18
+
19
+ def completed?
20
+ @completed
21
+ end
22
+
23
+ def initialize_context(hash)
24
+ @context = nil
25
+ end
26
+ end
27
+
28
+ class WatcherCallback < Callback
29
+ ## wexists, awexists, wget, awget, wget_children, awget_children
30
+ attr_reader :type, :state, :path
31
+
32
+ def initialize_context(hash)
33
+ @type, @state, @path, @context = hash[:type], hash[:state], hash[:path], hash[:context]
34
+ end
35
+ end
36
+
37
+ class DataCallback < Callback
38
+ ## aget, awget
39
+ attr_reader :return_code, :data, :stat
40
+
41
+ def initialize_context(hash)
42
+ @return_code, @data, @stat, @context = hash[:rc], hash[:data], hash[:stat], hash[:context]
43
+ end
44
+ end
45
+
46
+ class StringCallback < Callback
47
+ ## acreate, async
48
+ attr_reader :return_code, :string, :context
49
+
50
+ alias path string
51
+
52
+ def initialize_context(hash)
53
+ @return_code, @string, @context = hash[:rc], hash[:string], hash[:context]
54
+ end
55
+ end
56
+
57
+ class StringsCallback < Callback
58
+ ## aget_children, awget_children
59
+ attr_reader :return_code, :children, :stat
60
+
61
+ def initialize_context(hash)
62
+ @return_code, @children, @stat, @context = hash[:rc], hash[:strings], hash[:stat], hash[:context]
63
+ end
64
+ end
65
+
66
+ class StatCallback < Callback
67
+ ## aset, aexists, awexists
68
+ attr_reader :return_code, :stat
69
+
70
+ def initialize_context(hash)
71
+ @return_code, @stat, @context = hash[:rc], hash[:stat], hash[:context]
72
+ end
73
+ end
74
+
75
+ class VoidCallback < Callback
76
+ ## adelete, aset_acl, add_auth
77
+ attr_reader :return_code
78
+
79
+ def initialize_context(hash)
80
+ @return_code, @context = hash[:rc], hash[:context]
81
+ end
82
+ end
83
+
84
+ class ACLCallback < Callback
85
+ ## aget_acl
86
+ attr_reader :return_code, :acl, :stat
87
+ def initialize_context(hash)
88
+ @return_code, @acl, @stat, @context = hash[:rc], hash[:acl], hash[:stat], hash[:context]
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,174 @@
1
+ require 'zookeeper/exceptions'
2
+
3
+ module ZookeeperCommon
4
+ # sigh, i guess define this here?
5
+ ZKRB_GLOBAL_CB_REQ = -1
6
+
7
+ def event_dispatch_thread?
8
+ @dispatcher && (@dispatcher == Thread.current)
9
+ end
10
+
11
+ protected
12
+ def get_next_event(blocking=true)
13
+ @event_queue.pop(!blocking).tap do |event|
14
+ logger.debug { "#{self.class}##{__method__} delivering event #{event.inspect}" }
15
+ end
16
+ rescue ThreadError
17
+ nil
18
+ end
19
+
20
+ def setup_call(meth_name, opts)
21
+ req_id = nil
22
+ @mutex.synchronize {
23
+ req_id = @current_req_id
24
+ @current_req_id += 1
25
+ setup_completion(req_id, meth_name, opts) if opts[:callback]
26
+ setup_watcher(req_id, opts) if opts[:watcher]
27
+ }
28
+ req_id
29
+ end
30
+
31
+ def setup_watcher(req_id, call_opts)
32
+ @watcher_reqs[req_id] = { :watcher => call_opts[:watcher],
33
+ :context => call_opts[:watcher_context] }
34
+ end
35
+
36
+ # as a hack, to provide consistency between the java implementation and the C
37
+ # implementation when dealing w/ chrooted connections, we override this in
38
+ # ext/zookeeper_base.rb to wrap the callback in a chroot-path-stripping block.
39
+ #
40
+ # we don't use meth_name here, but we need it in the C implementation
41
+ #
42
+ def setup_completion(req_id, meth_name, call_opts)
43
+ @completion_reqs[req_id] = { :callback => call_opts[:callback],
44
+ :context => call_opts[:callback_context] }
45
+ end
46
+
47
+ def get_watcher(req_id)
48
+ @mutex.synchronize {
49
+ (req_id == ZKRB_GLOBAL_CB_REQ) ? @watcher_reqs[req_id] : @watcher_reqs.delete(req_id)
50
+ }
51
+ end
52
+
53
+ def get_completion(req_id)
54
+ @mutex.synchronize { @completion_reqs.delete(req_id) }
55
+ end
56
+
57
+ def setup_dispatch_thread!
58
+ logger.debug { "starting dispatch thread" }
59
+ @dispatcher ||= Thread.new do
60
+ while true
61
+ begin
62
+ dispatch_next_callback(get_next_event(true))
63
+ rescue QueueWithPipe::ShutdownException
64
+ logger.info { "dispatch thread exiting, got shutdown exception" }
65
+ break
66
+ rescue Exception => e
67
+ $stderr.puts ["#{e.class}: #{e.message}", e.backtrace.map { |n| "\t#{n}" }.join("\n")].join("\n")
68
+ end
69
+ end
70
+ signal_dispatch_thread_exit!
71
+ end
72
+ end
73
+
74
+ # this method is part of the reopen/close code, and is responsible for
75
+ # shutting down the dispatch thread.
76
+ #
77
+ # @dispatcher will be nil when this method exits
78
+ #
79
+ def stop_dispatch_thread!
80
+ logger.debug { "#{self.class}##{__method__}" }
81
+
82
+ if @dispatcher
83
+ if @dispatcher.join(0)
84
+ @dispatcher = nil
85
+ return
86
+ end
87
+
88
+ @mutex.synchronize do
89
+ event_queue.graceful_close!
90
+
91
+ # we now release the mutex so that dispatch_next_callback can grab it
92
+ # to do what it needs to do while delivering events
93
+ #
94
+ # wait for a maximum of 2 sec for dispatcher to signal exit (should be
95
+ # fast)
96
+ @dispatch_shutdown_cond.wait(2)
97
+
98
+ # wait for another 2 sec for the thread to join
99
+ unless @dispatcher.join(2)
100
+ logger.error { "Dispatch thread did not join cleanly, continuing" }
101
+ end
102
+ @dispatcher = nil
103
+ end
104
+ end
105
+ end
106
+
107
+ def signal_dispatch_thread_exit!
108
+ @mutex.synchronize do
109
+ logger.debug { "dispatch thread exiting!" }
110
+ @dispatch_shutdown_cond.broadcast
111
+ end
112
+ end
113
+
114
+ def dispatch_next_callback(hash)
115
+ return nil unless hash
116
+
117
+ Zookeeper.logger.debug { "get_next_event returned: #{prettify_event(hash).inspect}" }
118
+
119
+ is_completion = hash.has_key?(:rc)
120
+
121
+ hash[:stat] = ZookeeperStat::Stat.new(hash[:stat]) if hash.has_key?(:stat)
122
+ hash[:acl] = hash[:acl].map { |acl| ZookeeperACLs::ACL.new(acl) } if hash[:acl]
123
+
124
+ callback_context = is_completion ? get_completion(hash[:req_id]) : get_watcher(hash[:req_id])
125
+
126
+ # When connectivity to the server has been lost (as indicated by SESSION_EVENT)
127
+ # we want to rerun the callback at a later time when we eventually do have
128
+ # a valid response.
129
+ if hash[:type] == ZookeeperConstants::ZOO_SESSION_EVENT
130
+ is_completion ? setup_completion(hash[:req_id], callback_context) : setup_watcher(hash[:req_id], callback_context)
131
+ end
132
+ if callback_context
133
+ callback = is_completion ? callback_context[:callback] : callback_context[:watcher]
134
+
135
+ hash[:context] = callback_context[:context]
136
+
137
+ # TODO: Eventually enforce derivation from Zookeeper::Callback
138
+ if callback.respond_to?(:call)
139
+ callback.call(hash)
140
+ else
141
+ # puts "dispatch_next_callback found non-callback => #{callback.inspect}"
142
+ end
143
+ else
144
+ logger.warn { "Duplicate event received (no handler for req_id #{hash[:req_id]}, event: #{hash.inspect}" }
145
+ end
146
+ true
147
+ end
148
+
149
+ def assert_supported_keys(args, supported)
150
+ unless (args.keys - supported).empty?
151
+ raise ZookeeperExceptions::ZookeeperException::BadArguments, # this heirarchy is kind of retarded
152
+ "Supported arguments are: #{supported.inspect}, but arguments #{args.keys.inspect} were supplied instead"
153
+ end
154
+ end
155
+
156
+ def assert_required_keys(args, required)
157
+ unless (required - args.keys).empty?
158
+ raise ZookeeperExceptions::ZookeeperException::BadArguments,
159
+ "Required arguments are: #{required.inspect}, but only the arguments #{args.keys.inspect} were supplied."
160
+ end
161
+ end
162
+
163
+ private
164
+ def prettify_event(hash)
165
+ hash.dup.tap do |h|
166
+ # pretty up the event display
167
+ h[:type] = ZookeeperConstants::EVENT_TYPE_NAMES.fetch(h[:type]) if h[:type]
168
+ h[:state] = ZookeeperConstants::STATE_NAMES.fetch(h[:state]) if h[:state]
169
+ h[:req_id] = :global_session if h[:req_id] == -1
170
+ end
171
+ end
172
+ end
173
+
174
+ require 'zookeeper/common/queue_with_pipe'