Class: Console::Mux::CommandSet

Inherits:
Object
  • Object
show all
Includes:
Events
Defined in:
lib/console/mux/command_set.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Events

#event_handlers, #on

Constructor Details

#initializeCommandSet

Returns a new instance of CommandSet.



49
50
51
52
53
54
55
56
# File 'lib/console/mux/command_set.rb', line 49

def initialize
  @max_width = 0
  @commands = Array.new
  @commands_by_name = Hash.new

  @processes = Hash.new
  @stopped_at = Hash.new
end

Instance Attribute Details

#max_widthObject (readonly)

Returns the value of attribute max_width.



47
48
49
# File 'lib/console/mux/command_set.rb', line 47

def max_width
  @max_width
end

Class Method Details

.join(processes) ⇒ Object

Yield to the block only after all processes are stopped. Does not check that all processes are actually running; just waits for an :exit event from each.

Parameters:



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/console/mux/command_set.rb', line 34

def join(processes)
  pending_exit = processes.size
  processes.each do |proc|
    proc.on(:exit) do
      pending_exit -= 1
      if pending_exit == 0 && block_given?
        yield
      end
    end
  end
end

Instance Method Details

#[](name) ⇒ Object



110
111
112
# File 'lib/console/mux/command_set.rb', line 110

def [](name)
  @commands_by_name[name]
end

#add(command) ⇒ String

Add a command to this CommandSet.

command.name if required to be unique within this CommandSet

Parameters:

Returns:

  • (String)

    the command name, which may be different from



70
71
72
73
74
75
76
77
78
# File 'lib/console/mux/command_set.rb', line 70

def add(command)
  name = unique_name(command.name)

  @commands << command
  @commands_by_name[name] = command
  @max_width = [@max_width, name.size].max

  name
end

#add_and_start(command) ⇒ Object

Add a command (see #add) and start it (see #start).



59
60
61
62
# File 'lib/console/mux/command_set.rb', line 59

def add_and_start(command)
  name = add(command)
  start(name)
end

#countObject



212
213
214
# File 'lib/console/mux/command_set.rb', line 212

def count
  "#{@commands.size} commands with #{@processes.size} running"
end

#each(&block) ⇒ Object



106
107
108
# File 'lib/console/mux/command_set.rb', line 106

def each(&block)
  @commands.each(&block)
end

#include?(command) ⇒ Boolean

TODO: make this work? def merge(command)

if i = @commands.first_index(command)
  @commands[i] = command
  @commands_by_name[command.name] = command
else
  add(command)
end

end

Returns:

  • (Boolean)


98
99
100
# File 'lib/console/mux/command_set.rb', line 98

def include?(command)
  @commands.include?(command)
end

#join(&block) ⇒ Object

When all currently-running processes stop, yield to the block



145
146
147
# File 'lib/console/mux/command_set.rb', line 145

def join(&block)
  self.class.join(@processes.values, &block)
end

#pretty_bytes(bytes) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/console/mux/command_set.rb', line 175

def pretty_bytes(bytes)
  if bytes < 1024
    "#{bytes}B"
  elsif bytes < 1024 * 1024
    "#{bytes/1024} kiB"
  elsif bytes < 1024* 1024 * 1024
    "#{bytes/1024/1024} MiB"
  else
    "%0.2d GiB" % (bytes.to_f/(1024**3))
  end
end

#pretty_seconds(secs) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
# File 'lib/console/mux/command_set.rb', line 163

def pretty_seconds(secs)
  if secs < 60
    "#{secs} s"
  elsif secs < (60 * 60)
    "#{secs/60} min"
  elsif secs < (60 * 60 * 24)
    "#{secs/60/60} hr"
  else
    "%0.1f days" % (secs/60.0/60.0/24.0)
  end
end

#remove(name) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/console/mux/command_set.rb', line 80

def remove(name)
  return unless @commands_by_name[name]

  stop(name) rescue nil
  @stopped_at.delete(name)
  @commands.delete(@commands_by_name.delete(name))
end

#restart(name) ⇒ Object

Stop and then start the process name.



150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/console/mux/command_set.rb', line 150

def restart(name)
  if proc = @processes[name]
    proc.on(:exit) do
      start(name)
    end
    proc.stop
  elsif @commands_by_name[name]
    start(name)
  else
    raise "no process for #{name}"
  end
end

#start(name) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/console/mux/command_set.rb', line 114

def start(name)
  if proc = @processes[name]
    raise "already have process for #{name}: #{proc.pid}"
  end
  
  @stopped_at.delete(name)
  proc = Process.start(@commands_by_name[name], name)
  proc.on(:exit) do
    @processes.delete(name)
    @stopped_at[name] = Time.now
    fire(:stopped) if @processes.empty?
  end
  @processes[name] = proc
  proc
end

#statusObject



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/console/mux/command_set.rb', line 187

def status
  fmt = "%-#{max_width}s %8s %12s %8s %10s\n"

  rows = []
  rows << fmt % ['NAME', 'PID', 'RSS', 'TIME', 'CPUTIME']
  @commands_by_name.each do |name, c|
    pid, rss, time, cputime =
      if proc = @processes[name]
        [proc.pid.to_s,
         pretty_bytes(proc.rss),
         proc.etime,
         proc.cputime]
      elsif @stopped_at[name]
        downtime = Time.now.to_i - @stopped_at[name].to_i
        ['-', "  down #{pretty_seconds(downtime)}", nil, nil]
      else
        ['-', "        (pending)", nil, nil]
      end
    
    rows << (fmt % [name, pid, rss, time, cputime])
  end

  rows
end

#stop(name) ⇒ Object



130
131
132
133
134
135
136
# File 'lib/console/mux/command_set.rb', line 130

def stop(name)
  if proc = @processes.delete(name)
    proc.stop
  else
    raise "no process for #{name}"
  end
end

#stop_allObject



138
139
140
141
142
# File 'lib/console/mux/command_set.rb', line 138

def stop_all
  @processes.each do |name, proc|
    proc.stop
  end
end

#stopped?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/console/mux/command_set.rb', line 102

def stopped?
  @processes.empty?
end