lib/engineyard-serverside/servers.rb in engineyard-serverside-2.0.4 vs lib/engineyard-serverside/servers.rb in engineyard-serverside-2.0.5.pre
- old
+ new
@@ -61,30 +61,44 @@
@cache[roles_set] ||= select { |server| server.matches_roles?(roles_set) }
end
end
# Run a command on this set of servers.
- def run(shell, cmd, &blk)
- run_on_servers(shell, 'sh -l -c', cmd, &blk)
+ def run(shell, cmd, &block)
+ run_on_each do |server|
+ exec_cmd = server.command_on_server('sh -l -c', cmd, &block)
+ shell.logged_system(exec_cmd)
+ end
end
# Run a sudo command on this set of servers.
- def sudo(shell, cmd, &blk)
- run_on_servers(shell, 'sudo sh -l -c', cmd, &blk)
+ def sudo(shell, cmd, &block)
+ run_on_each do |server|
+ exec_cmd = server.command_on_server('sudo sh -l -c', cmd, &block)
+ shell.logged_system(exec_cmd)
+ end
end
- private
+ # Makes a thread for each server and executes the block,
+ # returning an array of return values
+ def map_in_parallel(&block)
+ threads = map { |server| Thread.new { block.call(server) } }
+ threads.map { |t| t.value }
+ end
- def run_on_servers(shell, prefix, cmd, &block)
- commands = map do |server|
- exec_cmd = server.command_on_server(prefix, cmd, &block)
- proc { shell.logged_system(exec_cmd) }
- end
+ def select_in_parallel(&block)
+ results = map_in_parallel { |server| block.call(server) ? server : nil }.compact
+ self.class.new results
+ end
- futures = EY::Serverside::Future.call(commands)
-
- unless EY::Serverside::Future.success?(futures)
- failures = futures.select {|f| f.error? }.map {|f| f.inspect}.join("\n")
+ # Makes a theard for each server and executes the block,
+ # Assumes that the return value of the block is a CommandResult
+ # and ensures that all the command results were successful.
+ def run_on_each(&block)
+ results = map_in_parallel(&block)
+ failures = results.reject {|result| result.success? }
+ if failures.any?
+ message = failures.map { |f| f.inspect }.join("\n")
raise EY::Serverside::RemoteFailure.new(failures)
end
end
end