Module: Browserctl::OrphanSweeper
- Defined in:
- lib/browserctl/orphan_sweeper.rb
Overview
Terminates orphaned Ferrum-spawned browser processes left behind by previous daemon or rspec runs that did not shut down cleanly (SIGKILL, OOM, crash).
Only targets processes whose argv contains the Ferrum temp user-data-dir marker AND whose PPID is 1 — so children of any live daemon are never touched.
Constant Summary collapse
- USER_DATA_DIR_MARKER =
"ferrum_user_data_dir_"
Class Method Summary collapse
- .find_orphans(processes) ⇒ Object
- .kill_process(pid, logger) ⇒ Object
- .list_processes ⇒ Object
- .supported_platform? ⇒ Boolean
- .sweep(logger: Browserctl.logger, lister: method(:list_processes), killer: method(:kill_process)) ⇒ Object
Class Method Details
.find_orphans(processes) ⇒ Object
24 25 26 27 28 29 30 |
# File 'lib/browserctl/orphan_sweeper.rb', line 24 def find_orphans(processes) processes.filter_map do |p| next unless p[:ppid] == 1 && p[:command].to_s.include?(USER_DATA_DIR_MARKER) p[:pid] end end |
.kill_process(pid, logger) ⇒ Object
44 45 46 47 48 49 50 51 |
# File 'lib/browserctl/orphan_sweeper.rb', line 44 def kill_process(pid, logger) Process.kill("TERM", pid) logger&.info("orphan sweep: terminated PID #{pid}") rescue Errno::ESRCH # already gone rescue Errno::EPERM logger&.debug("orphan sweep: no permission to kill PID #{pid}") end |
.list_processes ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/browserctl/orphan_sweeper.rb', line 32 def list_processes output = `ps -eo pid=,ppid=,command= 2>/dev/null` return [] if output.empty? output.lines.filter_map do |line| pid, ppid, command = line.strip.split(" ", 3) next unless pid && ppid && command { pid: pid.to_i, ppid: ppid.to_i, command: command } end end |
.supported_platform? ⇒ Boolean
53 54 55 |
# File 'lib/browserctl/orphan_sweeper.rb', line 53 def supported_platform? !RUBY_PLATFORM.match?(/mingw|mswin|windows/) end |
.sweep(logger: Browserctl.logger, lister: method(:list_processes), killer: method(:kill_process)) ⇒ Object
14 15 16 17 18 19 20 21 22 |
# File 'lib/browserctl/orphan_sweeper.rb', line 14 def sweep(logger: Browserctl.logger, lister: method(:list_processes), killer: method(:kill_process)) return unless supported_platform? orphans = find_orphans(lister.call) return if orphans.empty? logger&.info("orphan sweep: found #{orphans.size} stale browser process(es) from previous run") orphans.each { |pid| killer.call(pid, logger) } end |