Class: Stable::Services::ProcessManager
- Inherits:
-
Object
- Object
- Stable::Services::ProcessManager
- Defined in:
- lib/stable/services/process_manager.rb
Overview
Service for managing application processes
Class Method Summary collapse
- .find_rails_pid(port) ⇒ Object
-
.pid_alive?(pid) ⇒ Boolean
Check if a process with the given PID is still running.
- .start(target) ⇒ Object
- .stop(app) ⇒ Object
-
.validate_app_statuses ⇒ Object
Validate and clean up stale app statuses.
Class Method Details
.find_rails_pid(port) ⇒ Object
100 101 102 103 |
# File 'lib/stable/services/process_manager.rb', line 100 def self.find_rails_pid(port) pids = Stable::Utils::Platform.find_pids_by_port(port) pids.first end |
.pid_alive?(pid) ⇒ Boolean
Check if a process with the given PID is still running
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/stable/services/process_manager.rb', line 69 def self.pid_alive?(pid) return false unless pid # Use a cross-platform method to check if PID exists if RUBY_PLATFORM =~ /mingw|mswin|win32/ # Windows: use tasklist system("tasklist /FI \"PID eq #{pid}\" 2>NUL | find /I \"#{pid}\" >NUL") else # Unix-like systems: check /proc or use ps begin Process.kill(0, pid) true rescue Errno::ESRCH false rescue Errno::EPERM # Process exists but we don't have permission to signal it true end end end |
.start(target) ⇒ Object
7 8 9 10 11 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 42 43 44 45 46 |
# File 'lib/stable/services/process_manager.rb', line 7 def self.start(target) app = target.is_a?(String) ? AppRegistry.fetch(target) : target path = app[:path] port = app[:port] ruby = app[:ruby] gemset = Stable::Services::Ruby.gemset_for(app) if ruby && gemset Stable::Services::Ruby.ensure_rvm! system("bash -lc 'rvm #{ruby}@#{gemset} --create do true'") rvm_cmd = "rvm #{ruby}@#{gemset} do" elsif ruby rvm_cmd = "rvm #{ruby} do" else rvm_cmd = nil end log_file = File.join(path, 'log', 'stable.log') FileUtils.mkdir_p(File.dirname(log_file)) cmd = if rvm_cmd "cd \"#{path}\" && #{rvm_cmd} bundle exec rails s -p #{port} -b 127.0.0.1" else "cd \"#{path}\" && bundle exec rails s -p #{port} -b 127.0.0.1" end pid = spawn('bash', '-lc', cmd, out: log_file, err: log_file) Process.detach(pid) # Wait a moment for Rails to start, then find the actual Rails PID sleep 2 rails_pid = find_rails_pid(app[:port]) AppRegistry.update(app[:name], started_at: Time.now.to_i, pid: rails_pid || pid) rails_pid || pid end |
.stop(app) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/stable/services/process_manager.rb', line 48 def self.stop(app) return unless app[:port] pids = Stable::Utils::Platform.find_pids_by_port(app[:port]) if pids.empty? puts "No app running on port #{app[:port]}" else pids.each do |pid| Process.kill('TERM', pid.to_i) rescue StandardError nil end puts "Stopped #{app[:name]} on port #{app[:port]}" end AppRegistry.update(app[:name], started_at: nil, pid: nil) rescue Errno::ESRCH AppRegistry.update(app[:name], started_at: nil, pid: nil) end |
.validate_app_statuses ⇒ Object
Validate and clean up stale app statuses
91 92 93 94 95 96 97 98 |
# File 'lib/stable/services/process_manager.rb', line 91 def self.validate_app_statuses apps = AppRegistry.all apps.each do |app| next unless app[:started_at] && app[:pid] AppRegistry.update(app[:name], started_at: nil, pid: nil) unless pid_alive?(app[:pid]) end end |