Skip to content

Commit 5f98162

Browse files
committed
Use keepalive_interval option as IO select timeout
Net::SSH supports sending keepalive packets to the server to check whether the connection is still alive. For this to work, IO#select needs to be given a timeout so that the event loop can run periodically and send the packets.
1 parent 5b668d5 commit 5f98162

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

lib/net/ssh/multi/session.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ def loop(wait=nil, &block)
425425
# +false+ (the block returned +false+).
426426
def process(wait=nil, &block)
427427
realize_pending_connections!
428-
wait = @connect_threads.any? ? 0 : wait
428+
wait = @connect_threads.any? ? 0 : io_select_wait(wait)
429429

430430
return false unless preprocess(&block)
431431

@@ -441,6 +441,17 @@ def process(wait=nil, &block)
441441
end
442442
end
443443

444+
def io_select_wait(wait)
445+
return wait if wait
446+
return wait unless keepalive_interval
447+
keepalive_interval
448+
end
449+
450+
def keepalive_interval
451+
servers = server_list.select { |s| s.options[:keepalive] }
452+
servers.map { |s| s.options[:keepalive_interval] }.compact.min
453+
end
454+
444455
# Runs the preprocess stage on all servers. Returns false if the block
445456
# returns false, and true if there either is no block, or it returns true.
446457
# This is called as part of the #process method.

test/session_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,25 @@ def test_process_should_call_select_on_combined_readers_and_writers_from_all_ser
198198
IO.expects(:select).with([:a, :b, :c], [:a, :c], nil, 5).returns([[:b, :c], [:a, :c]])
199199
@session.process(5)
200200
end
201+
202+
def test_process_should_pass_minimum_keepalive_interval_as_io_select_timeout
203+
@session.use('h1', :keepalive => true)
204+
@session.use('h2', :keepalive_interval => 1)
205+
@session.use('h3', :keepalive => true, :keepalive_interval => 2)
206+
@session.use('h4', :keepalive => true, :keepalive_interval => 3)
207+
IO.expects(:select).with([], [], nil, 2)
208+
@session.process
209+
end
210+
211+
def test_process_should_pass_wait_argument_as_io_select_timeout_if_provided
212+
@session.use('h1', :keepalive => true, :keepalive_interval => 1)
213+
IO.expects(:select).with([], [], nil, 2)
214+
@session.process(2)
215+
end
216+
217+
def test_process_should_pass_nil_as_io_select_timeout_by_default
218+
@session.use('h1')
219+
IO.expects(:select).with([], [], nil, nil)
220+
@session.process
221+
end
201222
end

0 commit comments

Comments
 (0)