Class: Foreman::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/foreman/engine.rb

Direct Known Subclasses

CLI

Defined Under Namespace

Classes: CLI

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Engine

Create an Engine for running processes

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :formation (String) — default: all=1

    The process formation to use

  • :port (Fixnum) — default: 5000

    The base port to assign to processes

  • :root (String) — default: Dir.pwd

    The root directory from which to run processes



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/foreman/engine.rb', line 24

def initialize(options={})
  @options = options.dup

  @options[:formation] ||= (options[:concurrency] || "all=1")

  @env       = {}
  @mutex     = Mutex.new
  @names     = {}
  @processes = []
  @running   = {}
  @readers   = {}
end

Instance Attribute Details

#envObject (readonly)

Returns the value of attribute env.



12
13
14
# File 'lib/foreman/engine.rb', line 12

def env
  @env
end

#optionsObject (readonly)

Returns the value of attribute options.



13
14
15
# File 'lib/foreman/engine.rb', line 13

def options
  @options
end

#processesObject (readonly)

Returns the value of attribute processes.



14
15
16
# File 'lib/foreman/engine.rb', line 14

def processes
  @processes
end

Instance Method Details

#base_portObject

Get the base port for this foreman instance



179
180
181
# File 'lib/foreman/engine.rb', line 179

def base_port
  (options[:port] || env["PORT"] || ENV["PORT"] || 5000).to_i
end

#clearObject

Clear the processes registered to this Engine



70
71
72
73
# File 'lib/foreman/engine.rb', line 70

def clear
  @names     = {}
  @processes = []
end

#each_processObject

Yield each Process in order



146
147
148
149
150
# File 'lib/foreman/engine.rb', line 146

def each_process
  process_names.each do |name|
    yield name, process(name)
  end
end

#environmentObject

deprecated



184
185
186
# File 'lib/foreman/engine.rb', line 184

def environment
  env
end

#formationObject

Get the process formation



122
123
124
# File 'lib/foreman/engine.rb', line 122

def formation
  @formation ||= parse_formation(options[:formation])
end

#killall(signal = "SIGTERM") ⇒ Object

Send a signal to all processesstarted by this Engine

Parameters:

  • signal (String) (defaults to: "SIGTERM")

    The signal to send to each process



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/foreman/engine.rb', line 101

def killall(signal="SIGTERM")
  if Foreman.windows?
    @running.each do |pid, (process, index)|
      system "sending #{signal} to #{name_for(pid)} at pid #{pid}"
      begin
        Process.kill(signal, pid)
      rescue Errno::ESRCH, Errno::EPERM
      end
    end
  else
    begin
      Process.kill "-#{signal}", Process.pid
    rescue Errno::ESRCH, Errno::EPERM
    end
  end
end

#load_env(filename) ⇒ Object

Load a .env file into the env for this Engine

Parameters:

  • filename (String)

    A .env file to load into the environment



91
92
93
94
95
# File 'lib/foreman/engine.rb', line 91

def load_env(filename)
  Foreman::Env.new(filename).entries do |name, value|
    @env[name] = value
  end
end

#load_procfile(filename) ⇒ Object

Register processes by reading a Procfile

Parameters:

  • filename (String)

    A Procfile from which to read processes to register



79
80
81
82
83
84
85
# File 'lib/foreman/engine.rb', line 79

def load_procfile(filename)
  options[:root] ||= File.dirname(filename)
  Foreman::Procfile.new(filename).entries do |name, command|
    register name, command, :cwd => options[:root]
  end
  self
end

#port_for(process, instance, base = nil) ⇒ Object

Get the port for a given process and offset

Parameters:

  • process (Foreman::Process)

    A Process associated with this engine

  • instance (Fixnum)

    The instance of the process



167
168
169
170
171
172
173
# File 'lib/foreman/engine.rb', line 167

def port_for(process, instance, base=nil)
  if base
    base + (@processes.index(process.process) * 100) + (instance - 1)
  else
    base_port + (@processes.index(process) * 100) + (instance - 1)
  end
end

#process(name) ⇒ Object

Get the Process for a specifid name

Parameters:

  • name (String)

    The process name



140
141
142
# File 'lib/foreman/engine.rb', line 140

def process(name)
  @names.invert[name]
end

#process_namesObject

List the available process names



130
131
132
# File 'lib/foreman/engine.rb', line 130

def process_names
  @processes.map { |p| @names[p] }
end

#register(name, command, options = {}) ⇒ Object

Register a process to be run by this Engine

Parameters:

  • name (String)

    A name for this process

  • command (String)

    The command to run

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :env (Hash)

    A custom environment for this process



60
61
62
63
64
65
66
# File 'lib/foreman/engine.rb', line 60

def register(name, command, options={})
  options[:env] ||= env
  options[:cwd] ||= File.dirname(command.split(" ").first)
  process = Foreman::Process.new(command, options)
  @names[process] = name
  @processes << process
end

#rootObject

Get the root directory for this Engine



156
157
158
# File 'lib/foreman/engine.rb', line 156

def root
  File.expand_path(options[:root] || Dir.pwd)
end

#startObject

Start the processes registered to this Engine



39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/foreman/engine.rb', line 39

def start
  trap("TERM") { puts "SIGTERM received"; terminate_gracefully }
  trap("INT")  { puts "SIGINT received";  terminate_gracefully }
  trap("HUP")  { puts "SIGHUP received";  terminate_gracefully } if ::Signal.list.keys.include? 'HUP'

  startup
  spawn_processes
  watch_for_output
  sleep 0.1
  watch_for_termination { terminate_gracefully }
  shutdown
end