Class: SwitchTower::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/switchtower/command.rb

Overview

This class encapsulates a single command to be executed on a set of remote machines, in parallel.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(servers, command, callback, options, actor) ⇒ Command

:nodoc:



8
9
10
11
12
13
14
15
# File 'lib/switchtower/command.rb', line 8

def initialize(servers, command, callback, options, actor) #:nodoc:
  @servers = servers
  @command = command.strip.gsub(/\r?\n/, "\\\n")
  @callback = callback
  @options = options
  @actor = actor
  @channels = open_channels
end

Instance Attribute Details

#actorObject (readonly)

Returns the value of attribute actor.



6
7
8
# File 'lib/switchtower/command.rb', line 6

def actor
  @actor
end

#commandObject (readonly)

Returns the value of attribute command.



6
7
8
# File 'lib/switchtower/command.rb', line 6

def command
  @command
end

#optionsObject (readonly)

Returns the value of attribute options.



6
7
8
# File 'lib/switchtower/command.rb', line 6

def options
  @options
end

#serversObject (readonly)

Returns the value of attribute servers.



6
7
8
# File 'lib/switchtower/command.rb', line 6

def servers
  @servers
end

Instance Method Details

#loggerObject

:nodoc:



17
18
19
# File 'lib/switchtower/command.rb', line 17

def logger #:nodoc:
  actor.logger
end

#process!Object

Processes the command in parallel on all specified hosts. If the command fails (non-zero return code) on any of the hosts, this will raise a RuntimeError.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/switchtower/command.rb', line 24

def process!
  since = Time.now
  loop do
    active = 0
    @channels.each do |ch|
      next if ch[:closed]
      active += 1
      ch.connection.process(true)
    end

    break if active == 0
    if Time.now - since >= 1
      since = Time.now
      @channels.each { |ch| ch.connection.ping! }
    end
    sleep 0.01 # a brief respite, to keep the CPU from going crazy
  end

  logger.trace "command finished"

  if failed = @channels.detect { |ch| ch[:status] != 0 }
    raise "command #{@command.inspect} failed on #{failed[:host]}"
  end

  self
end