zk 1.5.2 → 1.5.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.
- 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