Module: Tipi::Supervisor

Defined in:
lib/tipi/supervisor.rb

Class Method Summary collapse

Class Method Details

.controller_cmdObject



35
36
37
38
39
40
41
# File 'lib/tipi/supervisor.rb', line 35

def controller_cmd
  [
    'ruby',
    File.join(__dir__, 'controller.rb'),
    @opts.to_json
  ]
end

.replace_controllerObject



63
64
65
66
67
68
69
70
71
72
# File 'lib/tipi/supervisor.rb', line 63

def replace_controller
  puts "Replacing controller"
  old_watcher = @controller_watcher
  @controller_watcher = start_controller_watcher

  # TODO: we'll want to get some kind of signal from the new controller once it's ready
  sleep 1

  old_watcher.terminate(true)
end

.run(opts) ⇒ Object



9
10
11
12
13
14
# File 'lib/tipi/supervisor.rb', line 9

def run(opts)
  puts "Start supervisor pid: #{Process.pid}"
  @opts = opts
  @controller_watcher = start_controller_watcher
  supervise_loop
end

.start_controller_watcherObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/tipi/supervisor.rb', line 16

def start_controller_watcher
  spin do
    cmd = controller_cmd
    puts "Starting controller..."
    pid = Kernel.spawn(*cmd)
    @controller_pid = pid
    puts "Controller pid: #{pid}"
    _pid, status = Polyphony.backend_waitpid(pid)
    puts "Controller has terminated with status: #{status.inspect}"
    terminated = true
  ensure
    if pid && !terminated
      puts "Terminate controller #{pid.inspect}"
      Polyphony::Process.kill_process(pid)
    end
    Fiber.current.parent << pid
  end
end

.supervise_loopObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/tipi/supervisor.rb', line 43

def supervise_loop
  this_fiber = Fiber.current
  trap('SIGUSR2') { this_fiber << :replace_controller }
  loop do
    case (msg = receive)
    when :replace_controller
      replace_controller
    when Integer
      pid = msg
      if pid == @controller_pid
        puts 'Detected dead controller. Restarting...'
        exit!
        @controller_watcher.restart
      end
    else
      raise "Invalid message received: #{msg.inspect}"
    end
  end
end