DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Execute A Task Serially On Different Hosts, Not In Parallel

04.18.2007
| 3892 views |
  • submit to reddit
        // This code will let you define a task, using the same conventions as Capistrano's "task", that executes serially on the hosts defined by its role rather than in parallel.  This is useful if you are deploying to multiple live servers behind a load balancer, the deployment process takes down the server, and you want only one server down at a given time.

This efinitely uses magic.  we're not sure if this will work in future versions of Capistrano, but changing it should be relatively simple.

def serial_task(name, options = {}, &block)
  servers = self.roles[options[:roles]].collect {|server| server.host}
  task_syms = []
  servers.each do |hostname|
    role_sym = "_serial_task_#{name.to_s}_#{hostname}".to_sym
    task_sym = "_do_task_#{name.to_s}_#{hostname}".to_sym
    task_syms << task_sym
    role role_sym, hostname
    task task_sym, :roles => role_sym, &block
  end
  task name do
    task_syms.each do |t|
      self.send t
    end
  end
end

Here is an example.  Note the syntax is just the same as Capistrano's "task".
serial_task :pwd, :roles => web do
  run "pwd"
end