diff --git a/CHANGELOG b/CHANGELOG index 5e211044..3120f30c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ *SVN* +* Ping each SSH connection every 1s during command processing so that long-running commands don't cause the connection to timeout. + +* Add a 0.01s sleep during the command loop so that the CPU doesn't go ballistic while ST is doing its thing. + * Add :restart_via variable for specifying whether restart ought to use :sudo (default, use sudo) * Use SFTP for file transfers (if available). diff --git a/lib/switchtower/command.rb b/lib/switchtower/command.rb index 2ab6d249..6667b4b1 100644 --- a/lib/switchtower/command.rb +++ b/lib/switchtower/command.rb @@ -24,6 +24,7 @@ module SwitchTower def process! logger.debug "processing command" + since = Time.now loop do active = 0 @channels.each do |ch| @@ -33,6 +34,11 @@ module SwitchTower end break if active == 0 + if Time.now - since >= 1 + since = Time.now + @channels.each { |ch| ping_connection(ch.connection) } + end + sleep 0.01 # a brief respite, to keep the CPU from going crazy end logger.trace "command finished" @@ -46,6 +52,13 @@ module SwitchTower private + # send an SSH IGNORE packet (this ought to be added to Net::SSH itself, + # so that you could just do connection.ping! instead of the cryptic mess + # below... + def ping_connection(connection) + connection.send_message([2, 4, "ping"].pack("cNA*")) + end + def open_channels @servers.map do |server| @actor.sessions[server].open_channel do |channel|