class DigitalFabric::Executive

agent for managing DF service

Constants

INDEX_HTML
LOADAVG_REGEXP
TOP_CPU_IDLE_REGEXP
TOP_CPU_REGEXP
TOP_MEM_FREE_REGEXP
TOP_MEM_REGEXP

Attributes

last_service_stats[R]

Public Class Methods

new(service, route = { path: '/executive' }) click to toggle source
# File lib/tipi/digital_fabric/executive.rb, line 13
def initialize(service, route = { path: '/executive' })
  @service = service
  route[:executive] = true
  @service.mount(route, self)
  @current_request_count = 0
  # @updater = spin_loop(:executive_updater, interval: 10) { update_service_stats }
  update_service_stats
end

Public Instance Methods

current_request_count() click to toggle source
# File lib/tipi/digital_fabric/executive.rb, line 22
def current_request_count
  @current_request_count
end
format_sse_event(data) click to toggle source
# File lib/tipi/digital_fabric/executive.rb, line 60
def format_sse_event(data)
  "data: #{data}\n\n"
end
http_request(req) click to toggle source
# File lib/tipi/digital_fabric/executive.rb, line 26
def http_request(req)
  @current_request_count += 1
  case req.path
  when '/'
    req.respond(INDEX_HTML, 'Content-Type' => 'text/html')
  when '/stats'
    message = last_service_stats
    req.respond(message.to_json, { 'Content-Type' => 'text.json' })
  when '/stream/stats'
    stream_stats(req)
  when '/upload'
    req.respond("body: #{req.read.inspect}")
  else
    req.respond('Invalid path', { ':status' => Qeweney::Status::NOT_FOUND })
  end
rescue => e
  puts "Error: #{e.inspect}"
ensure
  @current_request_count -= 1
end
machine_stats() click to toggle source
# File lib/tipi/digital_fabric/executive.rb, line 77
def machine_stats
  top = `top -bn1 | head -n4`
  unless top =~ TOP_CPU_REGEXP && Regexp.last_match(1) =~ TOP_CPU_IDLE_REGEXP
    p top =~ TOP_CPU_REGEXP
    p Regexp.last_match(1)
    p Regexp.last_match(1) =~ TOP_CPU_IDLE_REGEXP
    raise 'Invalid output from top (cpu)'
  end
  cpu_utilization = 100 - Regexp.last_match(1).to_i
  
  unless top =~ TOP_MEM_REGEXP && Regexp.last_match(1) =~ TOP_MEM_FREE_REGEXP
    raise 'Invalid output from top (mem)'
  end

  mem_free = Regexp.last_match(1).to_f

  stats = `cat /proc/loadavg`
  raise 'Invalid output from /proc/loadavg' unless stats =~ LOADAVG_REGEXP
  load_avg = Regexp.last_match(1).to_f

  {
    mem_free: mem_free,
    cpu_utilization: cpu_utilization,
    load_avg: load_avg
  }
end
stream_stats(req) click to toggle source
# File lib/tipi/digital_fabric/executive.rb, line 47
def stream_stats(req)
  req.send_headers({ 'Content-Type' => 'text/event-stream' })

  every(10) do
    message = last_service_stats
    req.send_chunk(format_sse_event(message.to_json))
  end
rescue IOError, SystemCallError
  # ignore
ensure
  req.send_chunk("retry: 0\n\n", true) rescue nil
end
update_service_stats() click to toggle source
# File lib/tipi/digital_fabric/executive.rb, line 64
def update_service_stats
  @last_service_stats = {
    service: @service.stats,
    machine: machine_stats
  }
end