zk 1.5.2 → 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Guardfile +10 -1
- data/lib/zk/client/base.rb +2 -4
- data/lib/zk/client/state_mixin.rb +1 -1
- data/lib/zk/client/threaded.rb +140 -48
- data/lib/zk/election.rb +3 -3
- data/lib/zk/event_handler.rb +1 -5
- data/lib/zk/event_handler_subscription/base.rb +1 -1
- data/lib/zk/locker/exclusive_locker.rb +1 -1
- data/lib/zk/locker/locker_base.rb +1 -1
- data/lib/zk/locker/shared_locker.rb +1 -1
- data/lib/zk/mongoid.rb +1 -0
- data/lib/zk/pool.rb +2 -2
- data/lib/zk/subscription.rb +1 -1
- data/lib/zk/threaded_callback.rb +2 -2
- data/lib/zk/version.rb +1 -1
- data/spec/shared/client_contexts.rb +4 -9
- data/spec/shared/client_examples.rb +9 -4
- data/spec/spec_helper.rb +3 -1
- data/spec/support/logging.rb +3 -4
- metadata +3 -3
data/Guardfile
CHANGED
@@ -26,11 +26,20 @@ guard 'rspec', :version => 2 do
|
|
26
26
|
when %r{^(?:zk/locker/locker_base|spec/shared/locker)}
|
27
27
|
Dir["spec/zk/locker/*_spec.rb"]
|
28
28
|
|
29
|
+
when %r{^zk/client/(?:base|state_mixin)}
|
30
|
+
Dir['spec/zk/{client,client/*,zookeeper}_spec.rb']
|
31
|
+
|
29
32
|
when 'zk' # .rb
|
30
33
|
'spec' # run all tests
|
31
34
|
|
32
35
|
else
|
33
|
-
"spec/#{m[1]}_spec.rb"
|
36
|
+
generic = "spec/#{m[1]}_spec.rb"
|
37
|
+
if test(?f, generic)
|
38
|
+
generic
|
39
|
+
else
|
40
|
+
$stderr.puts "RUNNING ALL TESTS"
|
41
|
+
'spec'
|
42
|
+
end
|
34
43
|
end
|
35
44
|
end
|
36
45
|
|
data/lib/zk/client/base.rb
CHANGED
@@ -51,7 +51,7 @@ module ZK
|
|
51
51
|
# the wrapped connection object
|
52
52
|
# @private
|
53
53
|
attr_reader :cnx
|
54
|
-
|
54
|
+
private :cnx
|
55
55
|
|
56
56
|
# maps from a symbol given as an option, to the numeric error constant that should
|
57
57
|
# not raise an exception
|
@@ -1020,7 +1020,7 @@ module ZK
|
|
1020
1020
|
def raw_event_handler(event)
|
1021
1021
|
end
|
1022
1022
|
|
1023
|
-
|
1023
|
+
private
|
1024
1024
|
# does the current pid match the one that created us?
|
1025
1025
|
def forked?
|
1026
1026
|
Process.pid != @pid
|
@@ -1038,7 +1038,6 @@ module ZK
|
|
1038
1038
|
check_rc(rv, opts)
|
1039
1039
|
end
|
1040
1040
|
|
1041
|
-
# @private
|
1042
1041
|
# XXX: make this actually call the method on cnx
|
1043
1042
|
def check_rc(rv_hash, inputs)
|
1044
1043
|
code = rv_hash[:rc]
|
@@ -1078,7 +1077,6 @@ module ZK
|
|
1078
1077
|
Set.new(ERROR_IGNORE_MAP.values_at(*sym_array))
|
1079
1078
|
end
|
1080
1079
|
|
1081
|
-
# @private
|
1082
1080
|
def setup_watcher!(watch_type, opts, &b)
|
1083
1081
|
event_handler.setup_watcher!(watch_type, opts, &b)
|
1084
1082
|
end
|
data/lib/zk/client/threaded.rb
CHANGED
@@ -45,10 +45,10 @@ module ZK
|
|
45
45
|
|
46
46
|
# @private
|
47
47
|
module Constants
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
RUNNING = :running
|
49
|
+
PAUSED = :paused
|
50
|
+
CLOSE_REQ = :close_requested
|
51
|
+
CLOSED = :closed
|
52
52
|
end
|
53
53
|
include Constants
|
54
54
|
|
@@ -161,13 +161,12 @@ module ZK
|
|
161
161
|
|
162
162
|
@reconnect = opts.fetch(:reconnect, true)
|
163
163
|
|
164
|
-
|
165
|
-
@cond = @mutex.new_cond
|
164
|
+
setup_locks
|
166
165
|
|
167
|
-
@
|
166
|
+
@client_state = RUNNING # this is to distinguish between *our* state and the underlying connection state
|
168
167
|
|
169
168
|
# this is the last status update we've received from the underlying connection
|
170
|
-
@last_cnx_state =
|
169
|
+
@last_cnx_state = nil
|
171
170
|
|
172
171
|
@retry_duration = opts.fetch(:retry_duration, nil).to_i
|
173
172
|
|
@@ -183,6 +182,15 @@ module ZK
|
|
183
182
|
|
184
183
|
connect if opts.fetch(:connect, true)
|
185
184
|
end
|
185
|
+
|
186
|
+
# ensure that the initializer and the reopen code set up the mutexes
|
187
|
+
# the same way (i.e. use a Monitor or a Mutex, no, really, I screwed
|
188
|
+
# this up once)
|
189
|
+
def setup_locks
|
190
|
+
@mutex = Monitor.new
|
191
|
+
@cond = @mutex.new_cond
|
192
|
+
end
|
193
|
+
private :setup_locks
|
186
194
|
|
187
195
|
# @private
|
188
196
|
def self.finalizer(hooks)
|
@@ -206,14 +214,18 @@ module ZK
|
|
206
214
|
|
207
215
|
logger.debug { "reopening everything, fork detected!" }
|
208
216
|
|
209
|
-
|
210
|
-
|
217
|
+
setup_locks
|
218
|
+
|
211
219
|
@pid = Process.pid
|
212
|
-
@
|
220
|
+
@client_state = RUNNING # reset state to running if we were paused
|
213
221
|
|
214
222
|
old_cnx, @cnx = @cnx, nil
|
215
223
|
old_cnx.close! if old_cnx # && !old_cnx.closed?
|
216
224
|
|
225
|
+
join_and_clear_reconnect_thread
|
226
|
+
|
227
|
+
@last_cnx_state = nil
|
228
|
+
|
217
229
|
@mutex.synchronize do
|
218
230
|
# it's important that we're holding the lock, as access to 'cnx' is
|
219
231
|
# synchronized, and we want to avoid a race where event handlers
|
@@ -228,11 +240,12 @@ module ZK
|
|
228
240
|
end
|
229
241
|
else
|
230
242
|
@mutex.synchronize do
|
231
|
-
if @
|
243
|
+
if @client_state == PAUSED
|
232
244
|
# XXX: what to do in this case? does it matter?
|
233
245
|
end
|
234
246
|
|
235
247
|
logger.debug { "reopening, no fork detected" }
|
248
|
+
@last_cnx_state = nil
|
236
249
|
@cnx.reopen(timeout) # ok, we werent' forked, so just reopen
|
237
250
|
end
|
238
251
|
end
|
@@ -252,30 +265,37 @@ module ZK
|
|
252
265
|
# @private
|
253
266
|
def pause_before_fork_in_parent
|
254
267
|
@mutex.synchronize do
|
255
|
-
raise InvalidStateError, "client must be running? when you call #{__method__}" unless (@
|
256
|
-
@
|
268
|
+
raise InvalidStateError, "client must be running? when you call #{__method__}" unless (@client_state == RUNNING)
|
269
|
+
@client_state = PAUSED
|
257
270
|
|
258
271
|
logger.debug { "#{self.class}##{__method__}" }
|
259
272
|
|
260
273
|
@cond.broadcast
|
261
274
|
end
|
262
275
|
|
276
|
+
join_and_clear_reconnect_thread
|
277
|
+
|
263
278
|
# the compact is here because the @cnx *may* be nil when this callback is fired by the
|
264
279
|
# ForkHook (in the case of ZK.open). The race is between the GC calling the finalizer
|
265
280
|
[@event_handler, @threadpool, @cnx].compact.each(&:pause_before_fork_in_parent)
|
266
281
|
ensure
|
267
|
-
logger.debug { "
|
282
|
+
logger.debug { "##{__method__} returning" }
|
268
283
|
end
|
269
284
|
|
270
285
|
# @private
|
271
286
|
def resume_after_fork_in_parent
|
272
287
|
@mutex.synchronize do
|
273
|
-
raise InvalidStateError, "client must be paused? when you call #{__method__}" unless (@
|
274
|
-
@
|
288
|
+
raise InvalidStateError, "client must be paused? when you call #{__method__}" unless (@client_state == PAUSED)
|
289
|
+
@client_state = RUNNING
|
275
290
|
|
276
|
-
logger.debug { "
|
291
|
+
logger.debug { "##{__method__}" }
|
277
292
|
|
278
|
-
|
293
|
+
if @cnx
|
294
|
+
@cnx.resume_after_fork_in_parent
|
295
|
+
spawn_reconnect_thread
|
296
|
+
end
|
297
|
+
|
298
|
+
[@event_handler, @threadpool].compact.each(&:resume_after_fork_in_parent)
|
279
299
|
|
280
300
|
@cond.broadcast
|
281
301
|
end
|
@@ -291,12 +311,14 @@ module ZK
|
|
291
311
|
#
|
292
312
|
def close!
|
293
313
|
@mutex.synchronize do
|
294
|
-
return if [:closed, :close_requested].include?(@
|
314
|
+
return if [:closed, :close_requested].include?(@client_state)
|
295
315
|
logger.debug { "moving to :close_requested state" }
|
296
|
-
@
|
316
|
+
@client_state = CLOSE_REQ
|
297
317
|
@cond.broadcast
|
298
318
|
end
|
299
319
|
|
320
|
+
join_and_clear_reconnect_thread
|
321
|
+
|
300
322
|
on_tpool = on_threadpool?
|
301
323
|
|
302
324
|
# Ok, so the threadpool will wait up to N seconds while joining each thread.
|
@@ -308,6 +330,7 @@ module ZK
|
|
308
330
|
# and wait for it to exit
|
309
331
|
#
|
310
332
|
shutdown_thread = Thread.new do
|
333
|
+
Thread.current[:name] = 'shutdown'
|
311
334
|
@threadpool.shutdown(10)
|
312
335
|
|
313
336
|
# this will call #close
|
@@ -315,7 +338,8 @@ module ZK
|
|
315
338
|
|
316
339
|
@mutex.synchronize do
|
317
340
|
logger.debug { "moving to :closed state" }
|
318
|
-
@
|
341
|
+
@client_state = CLOSED
|
342
|
+
@last_cnx_state = nil
|
319
343
|
@cond.broadcast
|
320
344
|
end
|
321
345
|
end
|
@@ -348,15 +372,6 @@ module ZK
|
|
348
372
|
@mutex.synchronize do
|
349
373
|
@last_cnx_state = event.state
|
350
374
|
|
351
|
-
if event.client_invalid? and @reconnect and not dead_or_dying?
|
352
|
-
logger.error { "Got event #{event.state_name}, calling reopen(0)! things may be messed up until this works itself out!" }
|
353
|
-
|
354
|
-
# reopen(0) means that we don't want to wait for the connection
|
355
|
-
# to reach the connected state before returning as we're on the
|
356
|
-
# event thread.
|
357
|
-
reopen(0)
|
358
|
-
end
|
359
|
-
|
360
375
|
@cond.broadcast # wake anyone waiting for a connection state update
|
361
376
|
end
|
362
377
|
rescue Exception => e
|
@@ -364,26 +379,47 @@ module ZK
|
|
364
379
|
end
|
365
380
|
|
366
381
|
def closed?
|
367
|
-
return true if @mutex.synchronize { @
|
382
|
+
return true if @mutex.synchronize { @client_state == CLOSED }
|
368
383
|
super
|
369
384
|
end
|
370
385
|
|
371
386
|
# are we in running (not-paused) state?
|
387
|
+
# @private
|
372
388
|
def running?
|
373
|
-
@mutex.synchronize { @
|
389
|
+
@mutex.synchronize { @client_state == RUNNING }
|
374
390
|
end
|
375
391
|
|
376
392
|
# are we in paused state?
|
393
|
+
# @private
|
377
394
|
def paused?
|
378
|
-
@mutex.synchronize { @
|
395
|
+
@mutex.synchronize { @client_state == PAUSED }
|
379
396
|
end
|
380
397
|
|
381
398
|
# has shutdown time arrived?
|
399
|
+
# @private
|
382
400
|
def close_requested?
|
383
|
-
@mutex.synchronize { @
|
401
|
+
@mutex.synchronize { @client_state == CLOSE_REQ }
|
384
402
|
end
|
385
403
|
|
386
|
-
|
404
|
+
# @private
|
405
|
+
def wait_until_connected_or_dying(timeout)
|
406
|
+
time_to_stop = Time.now + timeout
|
407
|
+
|
408
|
+
@mutex.synchronize do
|
409
|
+
while (@last_cnx_state != Zookeeper::ZOO_CONNECTED_STATE) && (Time.now < time_to_stop) && (@client_state == RUNNING)
|
410
|
+
@cond.wait(timeout)
|
411
|
+
end
|
412
|
+
|
413
|
+
logger.debug { "@last_cnx_state: #{@last_cnx_state.inspect}, time_left? #{Time.now.to_f < time_to_stop.to_f}, @client_state: #{@client_state.inspect}" }
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
private
|
418
|
+
# this is just here so we can see it in stack traces
|
419
|
+
def reopen_after_session_expired
|
420
|
+
reopen
|
421
|
+
end
|
422
|
+
|
387
423
|
# in the threaded version of the client, synchronize access around cnx
|
388
424
|
# so that callers don't wind up with a nil object when we're in the middle
|
389
425
|
# of reopening it
|
@@ -391,6 +427,58 @@ module ZK
|
|
391
427
|
@mutex.synchronize { @cnx }
|
392
428
|
end
|
393
429
|
|
430
|
+
def reconnect_thread_body
|
431
|
+
Thread.current[:name] = 'reconnect'
|
432
|
+
while @reconnect # too clever?
|
433
|
+
@mutex.synchronize do
|
434
|
+
# either we havne't seen a valid session update from this
|
435
|
+
# connection yet, or we're doing fine, so just wait
|
436
|
+
@cond.wait_while { !seen_session_state_event? or (valid_session_state? and (@client_state == RUNNING)) }
|
437
|
+
|
438
|
+
# we've entered into a non-running state, so we exit
|
439
|
+
# note: need to restart this thread after a fork in parent
|
440
|
+
if @client_state != RUNNING
|
441
|
+
logger.debug { "session failure watcher thread exiting, @client_state: #{@client_state}" }
|
442
|
+
return
|
443
|
+
end
|
444
|
+
|
445
|
+
# if we know that this session was valid once and it has now
|
446
|
+
# become invalid we call reopen
|
447
|
+
#
|
448
|
+
if seen_session_state_event? and not valid_session_state?
|
449
|
+
logger.debug { "session state was invalid, calling reopen" }
|
450
|
+
|
451
|
+
# reopen will reset @last_cnx_state so that
|
452
|
+
# seen_session_state_event? will return false until the first
|
453
|
+
# event has been delivered on the new connection
|
454
|
+
rv = reopen_after_session_expired
|
455
|
+
|
456
|
+
logger.debug { "reopen returned: #{rv.inspect}" }
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
ensure
|
461
|
+
logger.debug { "reconnect thread exiting" }
|
462
|
+
end
|
463
|
+
|
464
|
+
def join_and_clear_reconnect_thread
|
465
|
+
return unless @reconnect_thread
|
466
|
+
begin
|
467
|
+
# this should never time out but, just to make sure we don't hang forever
|
468
|
+
unless @reconnect_thread.join(30)
|
469
|
+
logger.error { "timed out waiting for reconnect thread to join! something is hosed!" }
|
470
|
+
end
|
471
|
+
rescue Exception => e
|
472
|
+
logger.error { "caught exception joining reconnect thread" }
|
473
|
+
logger.error { e.to_std_format }
|
474
|
+
end
|
475
|
+
@reconnect_thread = nil
|
476
|
+
end
|
477
|
+
|
478
|
+
def spawn_reconnect_thread
|
479
|
+
@reconnect_thread ||= Thread.new(&method(:reconnect_thread_body))
|
480
|
+
end
|
481
|
+
|
394
482
|
def call_and_check_rc(meth, opts)
|
395
483
|
if retry_duration = (opts.delete(:retry_duration) || @retry_duration)
|
396
484
|
begin
|
@@ -400,7 +488,7 @@ module ZK
|
|
400
488
|
|
401
489
|
wait_until_connected_or_dying(retry_duration)
|
402
490
|
|
403
|
-
if (@last_cnx_state != Zookeeper::ZOO_CONNECTED_STATE) || (Time.now > time_to_stop) || (@
|
491
|
+
if (@last_cnx_state != Zookeeper::ZOO_CONNECTED_STATE) || (Time.now > time_to_stop) || (@client_state != RUNNING)
|
404
492
|
raise e
|
405
493
|
else
|
406
494
|
retry
|
@@ -411,16 +499,20 @@ module ZK
|
|
411
499
|
end
|
412
500
|
end
|
413
501
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
@cond.wait(timeout)
|
420
|
-
end
|
502
|
+
# have we gotten a status event for the current connection?
|
503
|
+
# this method is not synchronized
|
504
|
+
def seen_session_state_event?
|
505
|
+
!!@last_cnx_state
|
506
|
+
end
|
421
507
|
|
422
|
-
|
423
|
-
|
508
|
+
# we've seen a session state from the cnx, and it was not "omg we're screwed"
|
509
|
+
# will return false if we havne't gotten a session event yet
|
510
|
+
#
|
511
|
+
# this method is not synchronized
|
512
|
+
def valid_session_state?
|
513
|
+
# this is kind of icky, but the SESSION_INVALID and AUTH_FAILED states
|
514
|
+
# are both negative numbers
|
515
|
+
@last_cnx_state and (@last_cnx_state >= 0)
|
424
516
|
end
|
425
517
|
|
426
518
|
def create_connection(*args)
|
@@ -428,14 +520,14 @@ module ZK
|
|
428
520
|
end
|
429
521
|
|
430
522
|
def dead_or_dying?
|
431
|
-
(@
|
523
|
+
(@client_state == CLOSE_REQ) || (@client_state == CLOSED)
|
432
524
|
end
|
433
525
|
|
434
|
-
private
|
435
526
|
def unlocked_connect(opts={})
|
436
527
|
return if @cnx
|
437
528
|
timeout = opts.fetch(:timeout, @connection_timeout)
|
438
529
|
@cnx = create_connection(@host, timeout, @event_handler.get_default_watcher_block)
|
530
|
+
spawn_reconnect_thread
|
439
531
|
end
|
440
532
|
end
|
441
533
|
end
|
data/lib/zk/election.rb
CHANGED
@@ -150,7 +150,7 @@ module ZK
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
-
|
153
|
+
private
|
154
154
|
def create_root_path!
|
155
155
|
@zk.mkdir_p(root_vote_path)
|
156
156
|
end
|
@@ -244,7 +244,7 @@ module ZK
|
|
244
244
|
end
|
245
245
|
end
|
246
246
|
|
247
|
-
|
247
|
+
private
|
248
248
|
# the inauguration, as it were
|
249
249
|
def acknowledge_win!
|
250
250
|
@zk.create(leader_ack_path, @data, :ephemeral => true)
|
@@ -411,7 +411,7 @@ module ZK
|
|
411
411
|
end
|
412
412
|
end
|
413
413
|
|
414
|
-
|
414
|
+
private
|
415
415
|
def the_king_is_dead
|
416
416
|
synchronize do
|
417
417
|
safe_call(*@leader_death_cbs)
|
data/lib/zk/event_handler.rb
CHANGED
@@ -196,7 +196,6 @@ module ZK
|
|
196
196
|
end
|
197
197
|
|
198
198
|
public
|
199
|
-
|
200
199
|
# used during shutdown to clear registered listeners
|
201
200
|
# @private
|
202
201
|
def clear! #:nodoc:
|
@@ -303,13 +302,11 @@ module ZK
|
|
303
302
|
end
|
304
303
|
end
|
305
304
|
|
306
|
-
|
307
|
-
# @private
|
305
|
+
private
|
308
306
|
def watcher_callback
|
309
307
|
Zookeeper::Callbacks::WatcherCallback.create { |event| process(event) }
|
310
308
|
end
|
311
309
|
|
312
|
-
# @private
|
313
310
|
def state_key(arg)
|
314
311
|
int =
|
315
312
|
case arg
|
@@ -326,7 +323,6 @@ module ZK
|
|
326
323
|
raise ArgumentError, "#{arg} is not a valid zookeeper state", caller
|
327
324
|
end
|
328
325
|
|
329
|
-
# @private
|
330
326
|
def safe_call(callbacks, *args)
|
331
327
|
callbacks.each do |cb|
|
332
328
|
next unless cb.respond_to?(:call)
|
data/lib/zk/mongoid.rb
CHANGED
data/lib/zk/pool.rb
CHANGED
@@ -140,7 +140,7 @@ module ZK
|
|
140
140
|
@state
|
141
141
|
end
|
142
142
|
|
143
|
-
|
143
|
+
private
|
144
144
|
def synchronize
|
145
145
|
@mutex.synchronize { yield }
|
146
146
|
end
|
@@ -255,7 +255,7 @@ module ZK
|
|
255
255
|
@mutex.synchronize { @connections.size < @max_clients }
|
256
256
|
end
|
257
257
|
|
258
|
-
|
258
|
+
private
|
259
259
|
def populate_pool!(num_cnx)
|
260
260
|
num_cnx.times { add_connection! }
|
261
261
|
end
|
data/lib/zk/subscription.rb
CHANGED
data/lib/zk/threaded_callback.rb
CHANGED
@@ -116,7 +116,7 @@ module ZK
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
-
|
119
|
+
private
|
120
120
|
# intentionally *not* synchronized
|
121
121
|
def spawn_dispatch_thread
|
122
122
|
@thread = Thread.new(&method(:dispatch_thread_body))
|
@@ -133,7 +133,7 @@ module ZK
|
|
133
133
|
@cond.wait(@mutex) while @array.empty? and @state == :running
|
134
134
|
|
135
135
|
if @state != :running
|
136
|
-
logger.
|
136
|
+
logger.debug { "ThreadedCallback, state is #{@state.inspect}, returning" }
|
137
137
|
return
|
138
138
|
end
|
139
139
|
|
data/lib/zk/version.rb
CHANGED
@@ -24,16 +24,11 @@ shared_context 'threaded client connection' do
|
|
24
24
|
# raise @threadpool_exception if @threadpool_exception
|
25
25
|
# logger.debug { "threaded client connection - after hook" }
|
26
26
|
|
27
|
-
if @zk.closed?
|
28
|
-
logger.debug { "zk was closed, calling reopen" }
|
29
|
-
@zk.reopen
|
30
|
-
end
|
27
|
+
@zk.close! if @zk and not @zk.closed?
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@zk.close!
|
36
|
-
wait_until(5) { @zk.closed? }
|
29
|
+
ZK.open(*connection_args) do |z|
|
30
|
+
z.rm_rf(@base_path)
|
31
|
+
end
|
37
32
|
|
38
33
|
# logger.debug { "threaded client connection - end after hook" }
|
39
34
|
end
|
@@ -298,15 +298,20 @@ shared_examples_for 'client' do
|
|
298
298
|
|
299
299
|
describe 'reconnection' do
|
300
300
|
it %[should if it receives a client_invalid? event] do
|
301
|
-
|
302
|
-
m.should_receive(:reopen).with(0).once
|
303
|
-
end
|
301
|
+
logger.debug { "about to cause the reconnection" }
|
304
302
|
|
305
303
|
props = { :session_event? => true, :client_invalid? => true, :state_name => 'ZOO_EXPIRED_SESSION_STATE', :state => Zookeeper::ZOO_EXPIRED_SESSION_STATE }
|
306
304
|
|
307
305
|
bogus_event = flexmock(:expired_session_event, props)
|
308
306
|
|
309
|
-
|
307
|
+
th = Thread.new do
|
308
|
+
@zk.raw_event_handler(bogus_event)
|
309
|
+
end
|
310
|
+
|
311
|
+
@zk.wait_until_connected_or_dying(5)
|
312
|
+
@zk.should be_connected
|
313
|
+
|
314
|
+
th.join(2).should == th
|
310
315
|
end
|
311
316
|
end # reconnection
|
312
317
|
|
data/spec/spec_helper.rb
CHANGED
@@ -110,8 +110,10 @@ class ::Thread
|
|
110
110
|
end
|
111
111
|
|
112
112
|
if RUBY_VERSION == '1.9.3'
|
113
|
+
Thread.current[:name] = 'main'
|
114
|
+
|
113
115
|
trap('USR1') do
|
114
|
-
threads = Thread.list.map { |th| { :inspect => th.inspect, :calback => th[:callback], :backtrace => th.backtrace } }
|
116
|
+
threads = Thread.list.map { |th| { :inspect => th.inspect, :name => th[:name], :calback => th[:callback], :backtrace => th.backtrace } }
|
115
117
|
pp threads
|
116
118
|
end
|
117
119
|
end
|
data/spec/support/logging.rb
CHANGED
@@ -3,14 +3,13 @@ module ZK
|
|
3
3
|
|
4
4
|
def self.logging_gem_setup
|
5
5
|
layout = ::Logging.layouts.pattern(
|
6
|
-
:pattern => '%.1l, [%d #%p] %
|
7
|
-
:date_pattern => '%
|
6
|
+
:pattern => '%.1l, [%d #%p] (%9.9T) %25.25c{2}: %m\n',
|
7
|
+
:date_pattern => '%H:%M:%S.%6N'
|
8
8
|
)
|
9
9
|
|
10
|
-
|
11
10
|
appender = ENV['ZK_DEBUG'] ? ::Logging.appenders.stderr : ::Logging.appenders.file(ZK::TEST_LOG_PATH)
|
12
11
|
appender.layout = layout
|
13
|
-
|
12
|
+
# appender.immediate_at = "debug,info,warn,error,fatal"
|
14
13
|
# appender.auto_flushing = true
|
15
14
|
appender.auto_flushing = 25
|
16
15
|
appender.flush_period = 5
|
metadata
CHANGED