summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamis Buck <jamis@37signals.com>2008-04-09 21:13:49 -0600
committerJamis Buck <jamis@37signals.com>2008-04-09 21:13:49 -0600
commit95429c249bfd39c7016f037242753f45fc0fd55d (patch)
tree69e8913d1c29ec9ad68fc77e098ccccaefdb0a42
parentb58b29794855c7d70a3488c5bf122172ce2cfb85 (diff)
downloadnet-ssh-multi-95429c249bfd39c7016f037242753f45fc0fd55d.tar.gz
update documentation to include lazy server evaluation, concurrent connection limiting, and connection error control. Also updated manifest file
-rw-r--r--Manifest10
-rw-r--r--README.rdoc4
-rw-r--r--lib/net/ssh/multi/dynamic_server.rb2
-rw-r--r--lib/net/ssh/multi/server.rb2
-rw-r--r--lib/net/ssh/multi/session.rb82
5 files changed, 96 insertions, 4 deletions
diff --git a/Manifest b/Manifest
index 37c6f4b..379fd01 100644
--- a/Manifest
+++ b/Manifest
@@ -1,9 +1,16 @@
CHANGELOG.rdoc
lib/net/ssh/multi/channel.rb
+lib/net/ssh/multi/channel_proxy.rb
+lib/net/ssh/multi/dynamic_server.rb
+lib/net/ssh/multi/pending_connection.rb
lib/net/ssh/multi/server.rb
+lib/net/ssh/multi/server_list.rb
lib/net/ssh/multi/session.rb
+lib/net/ssh/multi/session_actions.rb
+lib/net/ssh/multi/subsession.rb
lib/net/ssh/multi/version.rb
lib/net/ssh/multi.rb
+Manifest
Rakefile
README.rdoc
setup.rb
@@ -11,6 +18,7 @@ test/channel_test.rb
test/common.rb
test/multi_test.rb
test/server_test.rb
+test/session_actions_test.rb
test/session_test.rb
test/test_all.rb
-Manifest
+x.rb
diff --git a/README.rdoc b/README.rdoc
index d80580b..73ca258 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -11,7 +11,9 @@ This library is particularly useful for automating repetitive tasks that must be
== FEATURES:
* Easily manage multiple connections
-* Open channels, spawn processes, etc. on multiple connections in parallel.
+* Open channels, spawn processes, etc. on multiple connections in parallel
+* Transparently limit concurrent connections when dealing with large numbers of servers (Net::SSH::Multi::Session#concurrent_connections)
+* Specify a default gateway machine through which connections should be tunneled, or even specify a different gateway machine for each server
== SYNOPSIS:
diff --git a/lib/net/ssh/multi/dynamic_server.rb b/lib/net/ssh/multi/dynamic_server.rb
index 336dca7..0fec55a 100644
--- a/lib/net/ssh/multi/dynamic_server.rb
+++ b/lib/net/ssh/multi/dynamic_server.rb
@@ -37,7 +37,7 @@ module Net; module SSH; module Multi
# Returns the value for the given +key+ in the :properties hash of the
# +options+. If no :properties hash exists in +options+, this returns +nil+.
def [](key)
- (options[:properties] || {})[key]
+ (options[:properties] ||= {})[key]
end
# Iterates over every instantiated server record in this dynamic server.
diff --git a/lib/net/ssh/multi/server.rb b/lib/net/ssh/multi/server.rb
index a9d01aa..f53adb8 100644
--- a/lib/net/ssh/multi/server.rb
+++ b/lib/net/ssh/multi/server.rb
@@ -61,7 +61,7 @@ module Net; module SSH; module Multi
# properties are described via the +:properties+ key in the options hash
# when defining the Server.
def [](key)
- (options[:properties] || {})[key]
+ (options[:properties] ||= {})[key]
end
# Returns the port number to use for this connection.
diff --git a/lib/net/ssh/multi/session.rb b/lib/net/ssh/multi/session.rb
index 103e1c4..957533a 100644
--- a/lib/net/ssh/multi/session.rb
+++ b/lib/net/ssh/multi/session.rb
@@ -44,6 +44,81 @@ module Net; module SSH; module Multi
# Note that connections are established lazily, as soon as they are needed.
# You can force the connections to be opened immediately, though, using the
# #connect! method.
+ #
+ # == Concurrent Connection Limiting
+ #
+ # Sometimes you may be dealing with a large number of servers, and if you
+ # try to have connections open to all of them simultaneously you'll run into
+ # open file handle limitations and such. If this happens to you, you can set
+ # the #concurrent_connections property of the session. Net::SSH::Multi will
+ # then ensure that no more than this number of connections are ever open
+ # simultaneously.
+ #
+ # Net::SSH::Multi.start(:concurrent_connections => 5) do |session|
+ # # ...
+ # end
+ #
+ # Opening channels and executing commands will still work exactly as before,
+ # but Net::SSH::Multi will transparently close finished connections and open
+ # pending ones.
+ #
+ # == Controlling Connection Errors
+ #
+ # By default, Net::SSH::Multi will raise an exception if a connection error
+ # occurs when connecting to a server. This will typically bubble up and abort
+ # the entire connection process. Sometimes, however, you might wish to ignore
+ # connection errors, for instance when starting a daemon on a large number of
+ # boxes and you know that some of the boxes are going to be unavailable.
+ #
+ # To do this, simply set the #on_error property of the session to :ignore
+ # (or to :warn, if you want a warning message when a connection attempt
+ # fails):
+ #
+ # Net::SSH::Multi.start(:on_error => :ignore) do |session|
+ # # ...
+ # end
+ #
+ # The default is :fail, which causes the exception to bubble up. Additionally,
+ # you can specify a Proc object as the value for #on_error, which will be
+ # invoked with the server in question if the connection attempt fails. You
+ # can force the connection attempt to retry by throwing the :go symbol, with
+ # :retry as the payload, or force the exception to be reraised by throwing
+ # :go with :raise as the payload:
+ #
+ # handler = Proc.new do |server|
+ # server[:connection_attempts] ||= 0
+ # if server[:connection_attempts] < 3
+ # server[:connection_attempts] += 1
+ # throw :go, :retry
+ # else
+ # throw :go, :raise
+ # end
+ # end
+ #
+ # Net::SSH::Multi.start(:on_error => handler) do |session|
+ # # ...
+ # end
+ #
+ # Any other thrown value (or no thrown value at all) will result in the
+ # failure being ignored.
+ #
+ # == Lazily Evaluated Server Definitions
+ #
+ # Sometimes you might be dealing with an environment where you don't know the
+ # names or addresses of the servers until runtime. You can certainly dynamically
+ # build server names and pass them to #use, but if the operation to determine
+ # the server names is expensive, you might want to defer it until the server
+ # is actually needed (especially if the logic of your program is such that
+ # you might not even need to connect to that server every time the program
+ # runs).
+ #
+ # You can do this by passing a block to #use:
+ #
+ # session.use do |opt|
+ # lookup_ip_address_of_remote_host
+ # end
+ #
+ # See #use for more information about this usage.
class Session
include SessionActions
@@ -189,6 +264,13 @@ module Net; module SSH; module Multi
# server instances will be returned.
#
# server1, server2 = session.use "host1", "host2"
+ #
+ # If given a block, this will save the block as a Net::SSH::Multi::DynamicServer
+ # definition, to be evaluated lazily the first time the server is needed.
+ # The block will recive any options hash given to #use, and should return
+ # +nil+ (if no servers are to be added), a String or an array of Strings
+ # (to be interpreted as a connection specification), or a Server or an
+ # array of Servers.
def use(*hosts, &block)
options = hosts.last.is_a?(Hash) ? hosts.pop : {}
options = { :via => default_gateway }.merge(options)