Class: MainLoop::Dispatcher

Inherits:
Object
  • Object
show all
Includes:
MonitorMixin
Defined in:
lib/main_loop/dispatcher.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bus, timeout: 5, logger: nil) ⇒ Dispatcher

Returns a new instance of Dispatcher.



11
12
13
14
15
16
17
# File 'lib/main_loop/dispatcher.rb', line 11

def initialize(bus, timeout: 5, logger: nil)
  super()
  @bus = bus
  @timeout = timeout
  @handlers = []
  @logger = logger || Logger.new(nil)
end

Instance Attribute Details

#busObject (readonly)

Returns the value of attribute bus.



9
10
11
# File 'lib/main_loop/dispatcher.rb', line 9

def bus
  @bus
end

#handlersObject (readonly)

Returns the value of attribute handlers.



9
10
11
# File 'lib/main_loop/dispatcher.rb', line 9

def handlers
  @handlers
end

#loggerObject (readonly)

Returns the value of attribute logger.



9
10
11
# File 'lib/main_loop/dispatcher.rb', line 9

def logger
  @logger
end

Instance Method Details

#add_handler(handler) ⇒ Object



36
37
38
39
40
41
# File 'lib/main_loop/dispatcher.rb', line 36

def add_handler(handler)
  synchronize do
    handler.term if terminating?
    handlers << handler
  end
end

#log_statusObject

:nocov:



94
95
96
97
98
99
100
# File 'lib/main_loop/dispatcher.rb', line 94

def log_status
  total = handlers.size
  running = handlers.count(&:running?)
  finihsed = handlers.count(&:finished?)
  term_text = terminating? ? 'TERM' : ''
  logger.debug("Total:#{total} Running:#{running} Finihsed:#{finihsed}. #{term_text}".strip)
end

#need_force_kill?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/main_loop/dispatcher.rb', line 73

def need_force_kill?
  @terminating_at && (Time.now - @terminating_at) >= @timeout
end

#pidsObject



77
78
79
# File 'lib/main_loop/dispatcher.rb', line 77

def pids
  handlers.map{|h| h.pid rescue nil }.compact
end

#reap(statuses) ⇒ Object



19
20
21
22
23
# File 'lib/main_loop/dispatcher.rb', line 19

def reap(statuses)
  statuses.each do |(pid, status)|
    reap_by_id(pid, status)
  end
end

#reap_by_id(id, status) ⇒ Object



25
26
27
28
29
30
31
32
33
34
# File 'lib/main_loop/dispatcher.rb', line 25

def reap_by_id(id, status)
  synchronize do
    if (handler = handlers.find {|h| h.id == id })
      logger.info("Reap handler #{handler.name.inspect}. Status: #{status.inspect}")
      handler.reap(status)
    else
      logger.debug("Reap unknown handler. Status: #{status.inspect}. Skipped")
    end
  end
end

#termObject



47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/main_loop/dispatcher.rb', line 47

def term
  synchronize do
    if terminating?
      logger.info('Terminate FORCE all handlers')
      handlers.each(&:kill)
    else
      @terminating_at ||= Time.now
      logger.info('Terminate all handlers')
      handlers.each(&:term)
    end
  end
end

#terminating?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/main_loop/dispatcher.rb', line 43

def terminating?
  @terminating_at
end

#tickObject



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/main_loop/dispatcher.rb', line 60

def tick
  log_status if logger.debug?
  return unless terminating?

  try_exit!

  return if @killed || !need_force_kill?

  @killed = true
  logger.info('Killing all handlers by timeout')
  handlers.each(&:kill)
end

#try_exit!Object

:nocov:



82
83
84
85
86
87
88
89
90
# File 'lib/main_loop/dispatcher.rb', line 82

def try_exit!
  synchronize do
    return unless handlers.all?(&:finished?)

    logger.info('All handlers finished exiting...')
    status = handlers.all?(&:success?) ? 0 : 1
    exit status
  end
end