Class: Ignition::Manager
- Inherits:
-
Foreman::Engine
- Object
- Foreman::Engine
- Ignition::Manager
- Defined in:
- lib/ignition/engine/manager.rb
Constant Summary collapse
- BUNDLES_JSON =
"#{Ignition::ROOT_FOLDER}/bundles.json"
- BUNDLES_STATUS_JSON =
"#{Ignition::ROOT_FOLDER}/bundles_status.json"
Instance Attribute Summary collapse
-
#env ⇒ Object
readonly
Returns the value of attribute env.
Instance Method Summary collapse
- #add_process(bundle, index) ⇒ Object
- #apply_scale(bundle, count) ⇒ Object
- #bundle(id) ⇒ Object
- #bundles ⇒ Object
- #bundles_json ⇒ Object
- #bundles_status_json ⇒ Object
- #flush ⇒ Object
- #handle_hangup ⇒ Object
- #handle_interrupt ⇒ Object
- #handle_term_signal ⇒ Object
-
#initialize(broadcast_client) ⇒ Manager
constructor
A new instance of Manager.
- #kill_process_and_wait(pid, signal = "SIGTERM") ⇒ Object
-
#load_bundle(bh) ⇒ Object
end from foreman engine.
- #load_bundles ⇒ Object
- #logs(bundle_id) ⇒ Object
-
#name_for_bundle_index(bundle, index) ⇒ Object
OVERRIDES END.
- #network_daemons ⇒ Object
- #new_message(message) ⇒ Object
- #output(name, data) ⇒ Object
-
#process_count ⇒ Object
end.
- #process_ids ⇒ Object
- #recent_logs ⇒ Object
- #register(name, command, options = {}) ⇒ Object
- #register_bundle(bundle) ⇒ Object
- #register_bundles ⇒ Object
- #remove_old_pids(bundles) ⇒ Object
- #remove_process(bundle, index) ⇒ Object
-
#run(on_shutdown) ⇒ Object
end.
- #scale(name, count) ⇒ Object
- #shutdown ⇒ Object
- #spawn_process(bundle, process, n) ⇒ Object
-
#spawn_processes ⇒ Object
OVERRIDES START - more like monkey patches.
- #start_network_ping ⇒ Object
-
#startup ⇒ Object
start from foreman engine.
- #stop ⇒ Object
- #unload_bundle(bh) ⇒ Object
Constructor Details
#initialize(broadcast_client) ⇒ Manager
Returns a new instance of Manager.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/ignition/engine/manager.rb', line 12 def initialize(broadcast_client) #load the plugs super() @recent_logs = {} @registered_bundles = {} @process_ids = {} @shutdown = false @broadcast_client = broadcast_client @broadcast_client.(self) @network_daemons = {} env = ENV @bundles = load_bundles BundleHelper.prepare_bundles(@bundles) register_bundles register_signal_handlers start_network_ping end |
Instance Attribute Details
#env ⇒ Object (readonly)
Returns the value of attribute env.
7 8 9 |
# File 'lib/ignition/engine/manager.rb', line 7 def env @env end |
Instance Method Details
#add_process(bundle, index) ⇒ Object
289 290 291 292 293 294 |
# File 'lib/ignition/engine/manager.rb', line 289 def add_process(bundle,index) proc = process(bundle.id) pid =spawn_process(bundle,proc,index) bundle.status.add_pid(pid) # update_bundle_running_status(b) end |
#apply_scale(bundle, count) ⇒ Object
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/ignition/engine/manager.rb', line 261 def apply_scale(bundle,count) pp bundle puts bundle.status.scale.class puts "currently running #{bundle.status.scale}. Wanted #{count}" if (bundle.status.scale > count) # downscale to count. kill processes bundle.status.scale.downto(count+1) do |n| puts "apply_scale down #{n}" if n >= 1 remove_process(bundle,n) sleep(0.1) end end elsif (bundle.status.scale < count) # add processes # diff = count - bundle.status.scale puts "adding process." (bundle.status.scale+1).upto(count) do |n| puts "apply_scale up #{n}" if n >= 1 add_process(bundle,n) sleep(0.1) end end end # update_bundle_running_status(bundle) end |
#bundle(id) ⇒ Object
247 248 249 |
# File 'lib/ignition/engine/manager.rb', line 247 def bundle(id) @bundles.select{ |b| b.id == id }.first end |
#bundles ⇒ Object
43 44 45 |
# File 'lib/ignition/engine/manager.rb', line 43 def bundles @bundles end |
#bundles_json ⇒ Object
326 327 328 329 330 331 332 333 334 335 |
# File 'lib/ignition/engine/manager.rb', line 326 def bundles_json begin FileUtils.mkdir_p File.dirname(BUNDLES_JSON) File.read(BUNDLES_JSON) rescue Exception => exc # puts exc.message # puts exc.backtrace "[]" end end |
#bundles_status_json ⇒ Object
337 338 339 340 341 342 343 344 345 346 |
# File 'lib/ignition/engine/manager.rb', line 337 def bundles_status_json begin FileUtils.mkdir_p File.dirname(BUNDLES_STATUS_JSON) File.read(BUNDLES_STATUS_JSON) rescue Exception => exc # puts exc.message # puts exc.backtrace "[]" end end |
#flush ⇒ Object
362 363 364 365 366 367 368 369 |
# File 'lib/ignition/engine/manager.rb', line 362 def flush remove_old_pids(@bundles) File.write(BUNDLES_JSON,JSON.pretty_generate( @bundles.map{|b| b.reject{|k| k == "status"}} )) File.write(BUNDLES_STATUS_JSON,JSON.pretty_generate( @bundles.map do |b| { "id" => b.id , "status" => b.status } end )) end |
#handle_hangup ⇒ Object
197 198 199 200 201 202 203 204 |
# File 'lib/ignition/engine/manager.rb', line 197 def handle_hangup puts "custom SIGHUP received" terminate_gracefully @shutdown = true sleep(1) # exit(1) # Process.kill("EXIT", 0) end |
#handle_interrupt ⇒ Object
188 189 190 191 192 193 194 195 |
# File 'lib/ignition/engine/manager.rb', line 188 def handle_interrupt puts "custom SIGINT received" terminate_gracefully @shutdown = true sleep(1) # exit(1) # Process.kill("EXIT", 0) end |
#handle_term_signal ⇒ Object
179 180 181 182 183 184 185 186 |
# File 'lib/ignition/engine/manager.rb', line 179 def handle_term_signal puts "custom SIGTERM received" terminate_gracefully @shutdown = true sleep(1) # exit(1) # Process.kill("EXIT", 0) end |
#kill_process_and_wait(pid, signal = "SIGTERM") ⇒ Object
234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/ignition/engine/manager.rb', line 234 def kill_process_and_wait(pid,signal="SIGTERM") begin puts "killing process #{pid}" Process.kill signal, pid rescue Errno::ESRCH, Errno::EPERM end begin Process.wait(pid) puts "process finished #{pid}" rescue Errno::ECHILD end end |
#load_bundle(bh) ⇒ Object
end from foreman engine
84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/ignition/engine/manager.rb', line 84 def load_bundle(bh) if (!bundle(bh.id).nil?) raise "Bundle Exists. Unload bundle before adding." end bundle = Ignition::Bundle.new(bh) BundleHelper.prepare_bundle(bundle) @bundles << bundle register_bundle(bundle) flush end |
#load_bundles ⇒ Object
348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/ignition/engine/manager.rb', line 348 def load_bundles bundles = JSON.parse(bundles_json).map { |b| Ignition::Bundle.new(b) } # pp @bundles JSON.parse(bundles_status_json).each do |bs| # bundles b = bundles.select{ |b| b.id == bs.id }.first unless b.nil? b.status = Ignition::BundleStatus.new(bs.status) end end remove_old_pids(bundles) end |
#logs(bundle_id) ⇒ Object
407 408 409 410 411 412 |
# File 'lib/ignition/engine/manager.rb', line 407 def logs(bundle_id) # @recent_logs[bundle_id] proc_ids = @recent_logs.keys.select { |a| a.scan(/#{bundle_id}.\d+/).size > 0 } proc_ids.map { |b| @recent_logs[b].to_a }.flatten end |
#name_for_bundle_index(bundle, index) ⇒ Object
OVERRIDES END
208 209 210 |
# File 'lib/ignition/engine/manager.rb', line 208 def name_for_bundle_index(bundle,index) [ bundle.id, index.to_s ].compact.join(".") end |
#network_daemons ⇒ Object
384 385 386 |
# File 'lib/ignition/engine/manager.rb', line 384 def network_daemons @network_daemons end |
#new_message(message) ⇒ Object
378 379 380 381 382 |
# File 'lib/ignition/engine/manager.rb', line 378 def () # pp message @network_daemons[.handle] = Time.now end |
#output(name, data) ⇒ Object
69 70 71 72 73 74 75 76 77 |
# File 'lib/ignition/engine/manager.rb', line 69 def output(name, data) log = "#{Time.now.strftime("%H:%M:%S.%L")} - #{data}" puts "#{name} - #{log}" if @recent_logs[name].nil? @recent_logs[name] = FixedArray.new(100) end @recent_logs[name].push(log) end |
#process_count ⇒ Object
end
318 319 320 |
# File 'lib/ignition/engine/manager.rb', line 318 def process_count @process_ids.count end |
#process_ids ⇒ Object
322 323 324 |
# File 'lib/ignition/engine/manager.rb', line 322 def process_ids @process_ids end |
#recent_logs ⇒ Object
403 404 405 |
# File 'lib/ignition/engine/manager.rb', line 403 def recent_logs @recent_logs end |
#register(name, command, options = {}) ⇒ Object
170 171 172 173 174 175 176 177 |
# File 'lib/ignition/engine/manager.rb', line 170 def register(name, command, ={}) [:env] ||= env [:cwd] ||= File.dirname(command.split(" ").first) process = Foreman::Process.new(command, ) @names[process] = name @processes << process process #just return the process! end |
#register_bundle(bundle) ⇒ Object
54 55 56 57 58 59 60 61 62 63 |
# File 'lib/ignition/engine/manager.rb', line 54 def register_bundle(bundle) puts "Register bundle #{bundle.id}" = {} [:cwd] = bundle.cwd proc = register(bundle.id,bundle.command,) @registered_bundles[proc] = bundle end |
#register_bundles ⇒ Object
47 48 49 50 51 52 |
# File 'lib/ignition/engine/manager.rb', line 47 def register_bundles @bundles.each do |b| register_bundle(b) end pp @registered_bundles end |
#remove_old_pids(bundles) ⇒ Object
371 372 373 374 375 |
# File 'lib/ignition/engine/manager.rb', line 371 def remove_old_pids(bundles) bundles.each do |b| b.status.clean_pids end end |
#remove_process(bundle, index) ⇒ Object
296 297 298 299 300 301 302 303 304 |
# File 'lib/ignition/engine/manager.rb', line 296 def remove_process(bundle,index) name = name_for_bundle_index(bundle, index) pid = @process_ids[name] unless pid.nil? kill_process_and_wait(pid) # bundle.scale.pids.reject! { |p| p == pid } bundle.status.remove_pid(pid) end end |
#run(on_shutdown) ⇒ Object
end
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/ignition/engine/manager.rb', line 117 def run(on_shutdown) Thread.new { begin spawn_processes watch_for_output flush sleep 0.1 while(!@shutdown) # loop { pid = watch_for_termination { puts "child died" # terminate_gracefully } # puts "got pid notification #{pid}" if pid.nil? sleep(1) # puts "waiting for child process" end end puts "spawn thread complete." # loop { sleep(1000) } on_shutdown.call rescue Exception => exc puts exc. puts exc.backtrace terminate_gracefully on_shutdown.call end } end |
#scale(name, count) ⇒ Object
251 252 253 254 255 256 257 258 259 |
# File 'lib/ignition/engine/manager.rb', line 251 def scale(name,count) bundle_to_scale = bundle(name) apply_scale(bundle_to_scale,count) bundle_to_scale.status.scale = count flush end |
#shutdown ⇒ Object
79 80 |
# File 'lib/ignition/engine/manager.rb', line 79 def shutdown end |
#spawn_process(bundle, process, n) ⇒ Object
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/ignition/engine/manager.rb', line 212 def spawn_process(bundle,process,n) # 1.upto(count) do |n| reader, writer = create_pipe begin puts "starting process" name = name_for_bundle_index(bundle, n) pid = process.run(:output => writer, :env => { "PORT" => port_for(process, n).to_s, "PS" => name }) puts "started process" @process_ids[name] = pid writer.puts "started with pid #{pid}" rescue Errno::ENOENT writer.puts "unknown command: #{process.command}" end @running[pid] = [process, n] @readers[pid] = reader # end pid end |
#spawn_processes ⇒ Object
OVERRIDES START - more like monkey patches
157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/ignition/engine/manager.rb', line 157 def spawn_processes puts "override spawn process" @processes.each do |process| b = @registered_bundles[process] 1.upto(b.status.scale) do |n| pid = spawn_process(b,process,n) b.status.add_pid(pid) end # update_bundle_running_status(b) end pp @running end |
#start_network_ping ⇒ Object
388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/ignition/engine/manager.rb', line 388 def start_network_ping Thread.new { begin loop { sleep(1) # puts "sending ping" @broadcast_client.transmit("PING") } rescue Exception => exc puts exc. puts exc.backtrace end } end |
#startup ⇒ Object
start from foreman engine
66 67 |
# File 'lib/ignition/engine/manager.rb', line 66 def startup end |
#stop ⇒ Object
150 151 152 153 154 |
# File 'lib/ignition/engine/manager.rb', line 150 def stop puts "calling stop...." # terminate_gracefully # @shutdown = true end |
#unload_bundle(bh) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/ignition/engine/manager.rb', line 97 def unload_bundle(bh) if (bundle(bh.id).nil?) raise "Bundle #{bh.id} does NOT exist. Cannot unload." end #check for running bundles. if there are then raise error. need to be stopped first. # bundle = Ignition::Bundle.new(bh) # @bundles << bundle @bundles.reject! {|b| b.id == bh.id } # register_bundle(bundle) flush end |