Class: Console::Mux::Console

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

Constant Summary collapse

MARK_PERIOD =

seconds

60
BUFFER_LINES =
10000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Console

Returns a new instance of Console.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/console/mux/console.rb', line 45

def initialize(options={})
  @options = options
  @commands = CommandSet.new
  @default_options = Hash.new
  @base_dir = '.'

  @formatter = ColorFormatter.new

  @logger = Logger.new('process')
  logger.add ConsoleOutputter.new('console',
                                  self,
                                  :formatter => formatter)

  @buffer = BufferOutputter.new('buffer',
                                BUFFER_LINES,
                                :formatter => formatter)
  logger.add @buffer
end

Instance Attribute Details

#bufferObject (readonly)

Returns the value of attribute buffer.



43
44
45
# File 'lib/console/mux/console.rb', line 43

def buffer
  @buffer
end

#commandsObject (readonly)

Returns the value of attribute commands.



43
44
45
# File 'lib/console/mux/console.rb', line 43

def commands
  @commands
end

#default_optionsObject (readonly)

Returns the value of attribute default_options.



43
44
45
# File 'lib/console/mux/console.rb', line 43

def default_options
  @default_options
end

#formatterObject (readonly)

Returns the value of attribute formatter.



43
44
45
# File 'lib/console/mux/console.rb', line 43

def formatter
  @formatter
end

#loggerObject (readonly)

Returns the value of attribute logger.



43
44
45
# File 'lib/console/mux/console.rb', line 43

def logger
  @logger
end

#optionsObject (readonly)

Returns the value of attribute options.



43
44
45
# File 'lib/console/mux/console.rb', line 43

def options
  @options
end

Instance Method Details

#add(*opts_hashes) ⇒ Object

Like #run, but does not start any processes.



134
135
136
137
138
139
140
141
142
# File 'lib/console/mux/console.rb', line 134

def add(*opts_hashes)
  opts_hashes.map do |opts|
    if opts.kind_of? Array
      opts.map { |o| make_command_and_add(o) }
    else
      make_command_and_add(opts)
    end
  end
end

#lastlog(arg = //) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/console/mux/console.rb', line 246

def lastlog(arg=//)
  regex = case arg
          when String
            if arg.eql?(arg.downcase)
              /#{arg}/i
            else
              /#{arg}/
            end
          when Regexp
            arg
          else
            raise ArgumentError, 'need string or regexp'
          end

  @buffer.each do |msg|
    puts msg if msg =~ regex
  end
end

#load(file) ⇒ Object



84
85
86
87
88
89
90
91
92
93
# File 'lib/console/mux/console.rb', line 84

def load(file)
  old_base = @base_dir
  @base_dir = File.expand_path(File.dirname(file))
  begin
    @shell.instance_eval(File.read(file), file)
    @last_file = file
  ensure
    @base_dir = old_base
  end
end

#puts(message = '') ⇒ Object



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/console/mux/console.rb', line 265

def puts(message = '')
  # See http://stackoverflow.com/questions/1512028/gnu-readline-how-do-clear-the-input-line
  #
  # FIXME: Mac OS X 10.8 Mountain Lion seems to no longer have
  # Readline.line_buffer?? Or does it just return nil when
  # empty?
  buf = Readline.line_buffer
  print "\b \b" * buf.size if buf
  print "\r"
  begin
    $stdout.puts message
    $stdout.flush
  ensure
    ::Readline.forced_update_display
  end
end

#reset(&block) ⇒ Object

Stop all commands in the command set, then destroy the command set, starting with an empty one.



204
205
206
207
208
# File 'lib/console/mux/console.rb', line 204

def reset(&block)
  old_commands = commands
  @commands = CommandSet.new
  old_commands.join(&block)
end

#restart(name) ⇒ Object



220
221
222
223
# File 'lib/console/mux/console.rb', line 220

def restart(name)
  logger.info { "Restarting #{name}" }
  commands.restart(name)
end

#run(*opts_hashes) ⇒ Object

Run a single command, a sequence of commands, or a sequence of single and parallel commands with default shell argument expansion.

Each options hash is merged with the default options and then passed to Command.new.

If multiple command options are given, run them sequentially one-at-a-time. Only the final command will remain in the active command list; the others will be removed as they complete and exit.

If an array of command options is given, they will be run in parallel, even if part of sequential sequence. Thus you can specify run(c1, c2, [c3,c4,c5], c6) which will run commands 1 and 2 sequentially, then 3, 4 and 5 in parallel, then finally command 6 only after all previous commands complete.

In the following example, the first ls is run, and when it exits the next two ls instances are spawned in parallel. When those two exit, the final ls is run.

run({:command => 'ls'},
   [{:command => 'ls'}, {:command => 'ls'}],
   {:command => 'ls'})

Parameters:

  • *opts (Hash)

    one or more option hashes passed to Command.new.



128
129
130
131
# File 'lib/console/mux/console.rb', line 128

def run(*opts_hashes)
  names = add(*opts_hashes).compact
  seq_names(names)
end

#set_default_options(opts) ⇒ Object

Using set_ rather than ‘=’ style accessor so config file needn’t use self.default_options =.



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

def set_default_options(opts)
  @default_options = opts
end

#shutdownObject



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/console/mux/console.rb', line 225

def shutdown
  timer = EventMachine.add_timer(30) do
    logger.error { "could not halt all processes; giving up :(" }
    EventMachine.stop_event_loop
  end
  
  commands.on(:stopped) do
    EventMachine.cancel_timer(timer)

    # If not wrapped in next_tick, EventMachine doesn't exit
    # immediately (bug?)
    EventMachine.next_tick { EventMachine.stop_event_loop }
  end

  if commands.stopped?
    EventMachine.stop_event_loop
  else
    commands.stop_all
  end
end

#start(name) ⇒ Object



215
216
217
218
# File 'lib/console/mux/console.rb', line 215

def start(name)
  logger.info { "Starting #{name}" }
  commands.start(name)
end

#startupObject



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/console/mux/console.rb', line 64

def startup
  EventMachine.run do
    logger.info { 'Initializing' }

    EventMachine.add_periodic_timer(MARK_PERIOD) do
      now = Time.now.strftime('%Y-%m-%d %H:%M')
      logger.info { "#{now} have #{commands.count}" }
    end

    EventMachine.next_tick do
      load(options[:init_file]) if options[:init_file]
    end

    @shell = Shell.new(self)
    Ripl.start :binding => @shell.instance_eval { binding }
    EventMachine.watch_stdin(Ripl::Readline::EmInput,
                             :on_exit => proc { shutdown })
  end
end

#statusObject



198
199
200
# File 'lib/console/mux/console.rb', line 198

def status
  puts commands.status
end

#stop(name) ⇒ Object



210
211
212
213
# File 'lib/console/mux/console.rb', line 210

def stop(name)
  logger.info { "Stopping #{name}" }
  commands.stop(name)
end