Class: Invoker::ProcessManager

Inherits:
Object
  • Object
show all
Defined in:
lib/invoker/process_manager.rb

Overview

Class is responsible for managing all the processes Invoker is supposed to manage. Takes care of starting, stopping and restarting processes.

Constant Summary collapse

LABEL_COLORS =
[:green, :yellow, :blue, :magenta, :cyan]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeProcessManager

Returns a new instance of ProcessManager.



8
9
10
11
12
13
# File 'lib/invoker/process_manager.rb', line 8

def initialize
  @open_pipes = {}
  @workers = {}
  @worker_mutex = Mutex.new
  @thread_group = ThreadGroup.new
end

Instance Attribute Details

#open_pipesObject

Returns the value of attribute open_pipes.



6
7
8
# File 'lib/invoker/process_manager.rb', line 6

def open_pipes
  @open_pipes
end

#workersObject

Returns the value of attribute workers.



6
7
8
# File 'lib/invoker/process_manager.rb', line 6

def workers
  @workers
end

Instance Method Details

#get_worker_from_fd(fd) ⇒ Invoker::CommandWorker

Given a file descriptor returns the worker object

Parameters:

  • fd (IO)

    an IO object with valid file descriptor

Returns:



85
86
87
# File 'lib/invoker/process_manager.rb', line 85

def get_worker_from_fd(fd)
  open_pipes[fd.fileno]
end

#kill_workersObject



111
112
113
114
115
116
# File 'lib/invoker/process_manager.rb', line 111

def kill_workers
  @workers.each do |key, worker|
    kill_or_remove_process(worker.pid, "INT", worker.command_label)
  end
  @workers = {}
end

#load_env(directory = nil) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/invoker/process_manager.rb', line 89

def load_env(directory = nil)
  directory ||= ENV['PWD']

  if !directory || directory.empty? || !Dir.exist?(directory)
    return {}
  end

  default_env = File.join(directory, '.env')
  local_env = File.join(directory, '.env.local')
  env = {}

  if File.exist?(default_env)
    env.merge!(Dotenv::Environment.new(default_env))
  end

  if File.exist?(local_env)
    env.merge!(Dotenv::Environment.new(local_env))
  end

  env
end

#process_listObject

List currently running commands



119
120
121
# File 'lib/invoker/process_manager.rb', line 119

def process_list
  Invoker::IPC::Message::ListResponse.from_workers(workers)
end

#restart_process(reload_message) ⇒ Object

Receive a message from user to restart a Process



58
59
60
61
62
63
64
65
66
67
# File 'lib/invoker/process_manager.rb', line 58

def restart_process(reload_message)
  command_label = reload_message.process_name
  if stop_process(reload_message.remove_message)
    Invoker.commander.schedule_event(command_label, :worker_removed) do
      start_process_by_name(command_label)
    end
  else
    start_process_by_name(command_label)
  end
end

#run_power_serverObject



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/invoker/process_manager.rb', line 69

def run_power_server
  return unless Invoker.can_run_balancer?(false)

  powerup_id = Invoker::Power::Powerup.fork_and_start
  wait_on_pid("powerup_manager", powerup_id)
  at_exit do
    begin
      Process.kill("INT", powerup_id)
    rescue Errno::ESRCH; end
  end
end

#start_process(process_info) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/invoker/process_manager.rb', line 15

def start_process(process_info)
  m, s = PTY.open
  s.raw! # disable newline conversion.

  pid = run_command(process_info, s)

  s.close

  worker = CommandWorker.new(process_info.label, m, pid, select_color)

  add_worker(worker)
  wait_on_pid(process_info.label, pid)
end

#start_process_by_name(process_name) ⇒ Object

Start a process given their name

Parameters:

  • process_name (String)

    Command label of process specified in config file.



31
32
33
34
35
36
37
38
39
# File 'lib/invoker/process_manager.rb', line 31

def start_process_by_name(process_name)
  if process_running?(process_name)
    Invoker::Logger.puts "\nProcess '#{process_name}' is already running".colorize(:red)
    return false
  end

  process_info = Invoker.config.process(process_name)
  start_process(process_info) if process_info
end

#stop_process(remove_message) ⇒ Boolean

Remove a process from list of processes managed by invoker supervisor.It also kills the process before removing it from the list.

Parameters:

Returns:

  • (Boolean)

    if process existed and was removed else false



46
47
48
49
50
51
52
53
54
# File 'lib/invoker/process_manager.rb', line 46

def stop_process(remove_message)
  worker = workers[remove_message.process_name]
  command_label = remove_message.process_name
  return false unless worker
  signal_to_use = remove_message.signal || 'INT'

  Invoker::Logger.puts("Removing #{command_label} with signal #{signal_to_use}".colorize(:red))
  kill_or_remove_process(worker.pid, signal_to_use, command_label)
end