class OFlow::Inspector
Constants
- BY_ACTIVITY
- BY_COUNT
- BY_NAME
sort by values
- BY_QUEUE
- BY_STATE
Attributes
running[R]
Public Class Methods
new(env, port=6060)
click to toggle source
Calls superclass method
# File lib/oflow/inspector.rb, line 9 def initialize(env, port=6060) super() @env = env @running = true register('busy', self, :busy, 'returns the busy state of the system.', nil) register('list', self, :list, '[-r] [<id>] lists Flows and Tasks.', %|Shows a list of Flow and Task full names that fall under the id if one is provided, otherwise the top leve is assumed. If the -r option is specified then the names of all the Flows and Tasks under the named item are displayed.|) register('show', self, :show, '[-v] <id> displays a description of a Flow or Task.', %|Shows a description of the identified Flow or Task. If the -v option is specified then a detailed description of the Tasks is displayed which included the number of requests queued and the status of the Task. More -v arguments will give increasing more detail.|) register('start', self, :start, '[<task id>] start or restart a Task.', nil) register('step', self, :step, '[<task id>] step once.', %|Step once for the Task specfified or once for some Task that is waiting if no Task is identified.|) register('stop', self, :stop, '[<task id>] stops a Task.', nil) register('verbosity', self, :verbosity, '[<level>] show or set the verbosity or log level.', nil) register('watch', self, :watch, '[<task id> displays status of Tasks.', %|Displays the Task name, activity indicator, queued count, and number of requests processed. If the terminal supports real time updates the displays stays active until the X character is pressed. While running options are available for sorting on name, activity, or queue size.|) # register('debug', self, :debug, 'toggles debug mode.', nil) @server = ::OTerm::Server.new(self, port, false) end
Public Instance Methods
_dynamic_watch(listener, tasks)
click to toggle source
# File lib/oflow/inspector.rb, line 227 def _dynamic_watch(listener, tasks) o = listener.out sort_by = BY_NAME rev = false delay = 0.4 tasks.map! { |t| TaskStat.new(t) } lines = tasks.size + 3 h, w = o.screen_size() lines = h - 1 if lines > h - 1 o.clear_screen() done = false until done tasks.each { |ts| ts.refresh() } max = 6 max_n = 1 tasks.each do |ts| max = ts.name.size if max < ts.name.size max_n = ts.count.size if max_n < ts.count.size end # 5 for space between after, 3 for state, max_n for number max_q = w - max - 8 - max_n case sort_by when BY_NAME if rev tasks.sort! { |a,b| b.name <=> a.name } else tasks.sort! { |a,b| a.name <=> b.name } end when BY_ACTIVITY if rev tasks.sort! { |a,b| a.activity <=> b.activity } else tasks.sort! { |a,b| b.activity <=> a.activity } end when BY_QUEUE if rev tasks.sort! { |a,b| a.queued <=> b.queued } else tasks.sort! { |a,b| b.queued <=> a.queued } end when BY_COUNT if rev tasks.sort! { |a,b| a.proc_cnt <=> b.proc_cnt } else tasks.sort! { |a,b| b.proc_cnt <=> a.proc_cnt } end when BY_STATE if rev tasks.sort! { |a,b| a.state <=> b.state } else tasks.sort! { |a,b| b.state <=> a.state } end end o.set_cursor(1, 1) o.bold() o.underline() o.p("%1$*2$s ? %3$*4$s @ Queued %5$*6$s" % ['#', -max_n, 'Task', -max, ' ', max_q]) o.attrs_off() i = 2 tasks[0..lines].each do |ts| o.set_cursor(i, 1) o.p("%1$*2$s %5$c %3$*4$s " % [ts.count, max_n, ts.name, -max, ts.state]) o.set_cursor(i, max + max_n + 5) case ts.activity when 0 o.p(' ') when 1 o.p('.') when 2, 3 o.p('o') else o.p('O') end o.p(' ') qlen = ts.queued qlen = max_q if max_q < qlen if 0 < qlen o.reverse() o.p("%1$*2$d" % [ts.queued, -qlen]) o.attrs_off() end o.clear_to_end() i += 1 end o.bold() o.set_cursor(i, 1) if rev o.p("E) exit R) ") o.reverse() o.p("reverse") o.attrs_off() o.bold() o.p(" +) faster -) slower [%0.1f]" % [delay]) else o.p("E) exit R) reverse +) faster -) slower [%0.1f]" % [delay]) end i += 1 o.set_cursor(i, 1) o.p('sort by') { '#' => BY_COUNT, '?' => BY_STATE, 'N' => BY_NAME, 'A' => BY_ACTIVITY, 'Q' => BY_QUEUE }.each do |c,by| if by == sort_by o.p(" #{c}) ") o.reverse() o.p(by) o.attrs_off() o.bold() else o.p(" #{c}) #{by}") end end o.attrs_off() c = o.recv_wait(1, delay, /./) unless c.nil? case c[0] when 'e', 'E' done = true when 'n', 'N' sort_by = BY_NAME rev = false when 'a', 'A' sort_by = BY_ACTIVITY rev = false when 'q', 'Q' sort_by = BY_QUEUE rev = false when '#', 'c', 'C' sort_by = BY_COUNT rev = false when '?', 's', 'S' sort_by = BY_STATE rev = false when 'r', 'R' rev = !rev when '+' delay /= 2.0 unless delay <= 0.1 when '-' delay *= 2.0 unless 3.0 <= delay end end end o.pl() end
_parse_opt_id_args(args, opt, listener)
click to toggle source
# File lib/oflow/inspector.rb, line 422 def _parse_opt_id_args(args, opt, listener) opt_cnt = 0 id = nil args.strip! args.split(' ').each do |a| if '-' == a[0] a[1..-1].each_char do |c| if c == opt opt_cnt += 1 else listener.out.pl("--- -#{c} is not a valid option") return [0, nil, false] end end elsif !id.nil? listener.out.pl("--- Multiple Ids specified") return [0, nil, false] else id = a end end [opt_cnt, id, true] end
_walk(flow, recurse, listener, &block)
click to toggle source
# File lib/oflow/inspector.rb, line 446 def _walk(flow, recurse, listener, &block) if flow.respond_to?(:each_task) if recurse block.yield(flow) flow.each_task() do |task| _walk(task, true, listener, &block) end else flow.each_task() do |task| block.yield(task) end end else block.yield(flow) end end
busy(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 59 def busy(listener, args) if @env.busy?() listener.out.pl("One or more Tasks is busy.") else listener.out.pl("All Tasks are idle.") end end
debug(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 55 def debug(listener, args) @server.debug = !@server.debug end
flows(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 67 def flows(listener, args) @env.each_task() do |t| listener.out.pl(t.full_name) end end
greeting()
click to toggle source
# File lib/oflow/inspector.rb, line 51 def greeting() "Welcome to the Operations Flow Inspector." end
join()
click to toggle source
# File lib/oflow/inspector.rb, line 41 def join() @server.join() end
list(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 73 def list(listener, args) if nil == args @env.each_task() do |task| listener.out.pl(task.full_name) end return end recurse, id, ok = _parse_opt_id_args(args, 'r', listener) return unless ok if id.nil? flow = Env else flow = @env.locate(id) end if flow.nil? listener.out.pl("--- No Flow or Task found for #{id}") return end _walk(flow, recurse, listener) do |task| listener.out.pl(task.full_name) unless Env == task end end
show(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 96 def show(listener, args) if nil == args listener.out.pl("--- No Flow or Task specified") return end detail, id, ok = _parse_opt_id_args(args, 'v', listener) return unless ok task = @env.locate(id) if task.nil? listener.out.pl("--- Failed to find '#{id}'") return end listener.out.pl(task.describe(detail)) end
shutdown(listener, args)
click to toggle source
Calls superclass method
# File lib/oflow/inspector.rb, line 45 def shutdown(listener, args) super @running = false @env.shutdown() end
start(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 112 def start(listener, args) if nil == args || 0 == args.size() @env.start() listener.out.pl("All Tasks restarted") else args.strip! task = @env.locate(args) if task.nil? listener.out.pl("--- Failed to find '#{args}'") else task.start() listener.out.pl("#{task.full_name} restarted") end end end
step(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 128 def step(listener, args) lg = @env.log() stop_after = false if !lg.nil? && Task::STOPPED == lg.state lg.start() stop_after = true end if nil == args || 0 == args.size() task = Env else args.strip! task = @env.locate(args) end if task.nil? listener.out.pl("--- Failed to find '#{args}'") else task = task.step() if task.nil? listener.out.pl("--- No tasks in '#{args}' are stopped or have have queued requests") else listener.out.pl("#{task.full_name} stepped") end end lg.stop() if stop_after end
stop(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 155 def stop(listener, args) if nil == args || 0 == args.size() @env.stop() listener.out.pl("All Tasks stopped(paused)") else args.strip! task = @env.locate(args) if task.nil? listener.out.pl("--- Failed to find '#{args}'") else task.stop() listener.out.pl("#{task.full_name} stopped(paused)") end end end
tab(cmd, listener)
click to toggle source
Calls superclass method
# File lib/oflow/inspector.rb, line 372 def tab(cmd, listener) start = cmd.index(' ') if start.nil? super return end op = cmd[0...start] start = cmd.rindex(' ') pre = cmd[0...start] last = cmd[start + 1..-1] return if '-' == last[0] # Tab completion is different depending on the command. names = [] case op.downcase() when 'verbosity' names = ['fatal', 'error', 'warn', 'info', 'debug'].select { |s| s.start_with?(last.downcase()) } else # expect id or options with_colon = ':' == last[0] @env.walk_tasks(false) do |t| fn = t.full_name fn = fn[1..-1] unless with_colon names << fn if fn.start_with?(last) end end return if 0 == names.size if 1 == names.size listener.move_col(1000) listener.insert(names[0][last.size..-1]) listener.out.prompt() listener.out.p(listener.buf) else listener.out.pl() names.each do |name| listener.out.pl("#{pre} #{name}") end best = best_completion(last, names) if best == last listener.update_cmd(0) else listener.move_col(1000) listener.insert(best[last.size..-1]) listener.out.prompt() listener.out.p(listener.buf) end end end
verbosity(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 171 def verbosity(listener, args) lg = @env.log if lg.nil? listener.out.pl("--- No logger") return end lga = lg.actor if nil != args && 0 < args.size() args.strip! lg.receive(:severity, Box.new(args)) listener.out.pl("verbosity change pending") elsif lga.respond_to?(:severity) listener.out.pl("verbosity: #{lga.severity()}") else listener.out.pl("--- Logger does support requests for verbosity level") end end
watch(listener, args)
click to toggle source
# File lib/oflow/inspector.rb, line 189 def watch(listener, args) tasks = [] if args.nil? || 0 == args.size() @env.walk_tasks() { |t| tasks << t } else args.strip! task = @env.locate(args) if task.nil? listener.out.pl("--- Failed to find '#{args}'") return elsif task.kind_of?(HasTasks) task.walk_tasks() { |t| tasks << t } else tasks << task end end if listener.out.is_vt100? _dynamic_watch(listener, tasks) else max_len = 10 tasks.each do |t| len = t.full_name.size max_len = len if max_len < len end listener.out.pl(" %#{max_len}s %-11s %5s %9s" % ['Task Name', 'Q-cnt/max', 'busy?', 'processed']) tasks.each do |t| listener.out.pl(" %#{max_len}s %5d/%-5d %5s %9d" % [t.full_name, t.queue_count(), t.max_queue_count().to_i, t.busy?(), t.proc_count()]) end end end