Changeset 8924
- Timestamp:
- 02/22/08 04:07:16 (7 months ago)
- Files:
-
- tools/capistrano/CHANGELOG (modified) (1 diff)
- tools/capistrano/lib/capistrano/configuration/connections.rb (modified) (3 diffs)
- tools/capistrano/lib/capistrano/task_definition.rb (modified) (2 diffs)
- tools/capistrano/test/configuration/connections_test.rb (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
tools/capistrano/CHANGELOG
r8923 r8924 1 1 *SVN* 2 3 * Add support for :max_hosts option in task definition or run() [Rob Holland <rob@inversepath.com>] 2 4 3 5 * Distributed git support for better operability with remote_cache strategy [voidlock] tools/capistrano/lib/capistrano/configuration/connections.rb
r7205 r8924 1 2 require 'enumerator' 1 3 require 'capistrano/gateway' 2 4 require 'capistrano/ssh' … … 96 98 end 97 99 100 # Destroys sessions for each server in the list. 101 def teardown_connections_to(servers) 102 servers.each do |server| 103 @sessions[server].close 104 @sessions.delete(server) 105 end 106 end 107 98 108 # Determines the set of servers within the current task's scope and 99 109 # establishes connections to them, and then yields that list of … … 121 131 logger.trace "servers: #{servers.map { |s| s.host }.inspect}" 122 132 123 # establish connections to those servers, as necessary 124 begin 125 establish_connections_to(servers) 126 rescue ConnectionError => error 127 raise error unless task && task.continue_on_error? 128 error.hosts.each do |h| 129 servers.delete(h) 130 failed!(h) 133 max_hosts = (options[:max_hosts] || (task && task.max_hosts) || servers.size).to_i 134 is_subset = max_hosts < servers.size 135 136 # establish connections to those servers in groups of max_hosts, as necessary 137 servers.each_slice(max_hosts) do |servers_slice| 138 begin 139 establish_connections_to(servers_slice) 140 rescue ConnectionError => error 141 raise error unless task && task.continue_on_error? 142 error.hosts.each do |h| 143 servers_slice.delete(h) 144 failed!(h) 145 end 131 146 end 132 end133 147 134 begin 135 yield servers 136 rescue RemoteError => error 137 raise error unless task && task.continue_on_error? 138 error.hosts.each { |h| failed!(h) } 148 begin 149 yield servers_slice 150 rescue RemoteError => error 151 raise error unless task && task.continue_on_error? 152 error.hosts.each { |h| failed!(h) } 153 end 154 155 # if dealing with a subset (e.g., :max_hosts is less than the 156 # number of servers available) teardown the subset of connections 157 # that were just made, so that we can make room for the next subset. 158 teardown_connections_to(servers_slice) if is_subset 139 159 end 140 160 end tools/capistrano/lib/capistrano/task_definition.rb
r7205 r8924 4 4 # Represents the definition of a single task. 5 5 class TaskDefinition 6 attr_reader :name, :namespace, :options, :body, :desc, :on_error 6 attr_reader :name, :namespace, :options, :body, :desc, :on_error, :max_hosts 7 7 8 8 def initialize(name, namespace, options={}, &block) … … 10 10 @desc = @options.delete(:desc) 11 11 @on_error = options.delete(:on_error) 12 @max_hosts = options[:max_hosts] && options[:max_hosts].to_i 12 13 @body = block or raise ArgumentError, "a task requires a block" 13 14 @servers = nil tools/capistrano/test/configuration/connections_test.rb
r7373 r8924 218 218 @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns(list) 219 219 Capistrano::SSH.expects(:connect).times(2).raises(Exception).then.returns(:success) 220 @config.expects(:failed!).with(server("cap1"))221 220 @config.execute_on_servers do |servers| 222 221 assert_equal %w(cap2), servers.map { |s| s.host } … … 261 260 end 262 261 end 263 262 264 263 def test_connect_should_establish_connections_to_all_servers_in_scope 265 264 assert @config.sessions.empty? … … 270 269 assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host } 271 270 end 272 271 272 def test_execute_on_servers_should_only_run_on_tasks_max_hosts_hosts_at_once 273 cap1 = server("cap1") 274 cap2 = server("cap2") 275 connection1 = mock() 276 connection2 = mock() 277 connection1.expects(:close) 278 connection2.expects(:close) 279 @config.current_task = mock_task(:max_hosts => 1) 280 @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2]) 281 Capistrano::SSH.expects(:connect).times(2).returns(connection1).then.returns(connection2) 282 block_called = 0 283 @config.execute_on_servers do |servers| 284 block_called += 1 285 assert_equal 1, servers.size 286 end 287 assert_equal 2, block_called 288 end 289 290 def test_execute_on_servers_should_only_run_on_max_hosts_hosts_at_once 291 cap1 = server("cap1") 292 cap2 = server("cap2") 293 connection1 = mock() 294 connection2 = mock() 295 connection1.expects(:close) 296 connection2.expects(:close) 297 @config.current_task = mock_task(:max_hosts => 1) 298 @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2]) 299 Capistrano::SSH.expects(:connect).times(2).returns(connection1).then.returns(connection2) 300 block_called = 0 301 @config.execute_on_servers do |servers| 302 block_called += 1 303 assert_equal 1, servers.size 304 end 305 assert_equal 2, block_called 306 end 307 273 308 def test_connect_should_honor_once_option 274 309 assert @config.sessions.empty? … … 284 319 def mock_task(options={}) 285 320 continue_on_error = options[:on_error] == :continue 286 stub("task", :fully_qualified_name => "name", :options => options, :continue_on_error? => continue_on_error) 321 stub("task", 322 :fully_qualified_name => "name", 323 :options => options, 324 :continue_on_error? => continue_on_error, 325 :max_hosts => options[:max_hosts] 326 ) 287 327 end 288 328 end