Module: Palapala::Renderer::ChromeProcess

Defined in:
lib/palapala/renderer.rb

Overview

Manage the Chrome child process

Class Method Summary collapse

Class Method Details

.chrome_pathObject



136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/palapala/renderer.rb', line 136

def self.chrome_path
  return Palapala.headless_chrome_path if Palapala.headless_chrome_path

  case RbConfig::CONFIG["host_os"]
  when /darwin/
    "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
  when /linux/
    "/usr/bin/google-chrome" # or "/usr/bin/chromium-browser"
  when /win|mingw|cygwin/
    "#{ENV["ProgramFiles(x86)"]}\\Google\\Chrome\\Application\\chrome.exe"
  else
    raise "Unsupported OS"
  end
end

.chrome_process_healthy?Boolean

Returns:

  • (Boolean)


118
119
120
121
122
123
124
125
126
127
# File 'lib/palapala/renderer.rb', line 118

def self.chrome_process_healthy?
  return false if @chrome_process_id.nil?

  begin
    Process.kill(0, @chrome_process_id) # Check if the process is alive
    true
  rescue Errno::ESRCH, Errno::EPERM
    false
  end
end

.kill_chromeObject



129
130
131
132
133
134
# File 'lib/palapala/renderer.rb', line 129

def self.kill_chrome
  return if @chrome_process_id.nil?

  Process.kill("KILL", @chrome_process_id) # Kill the process
  Process.wait(@chrome_process_id) # Wait for the process to finish
end

.port_in_use?(port = 9222, host = "127.0.0.1") ⇒ Boolean

Returns:

  • (Boolean)


110
111
112
113
114
115
116
# File 'lib/palapala/renderer.rb', line 110

def self.port_in_use?(port = 9222, host = "127.0.0.1")
  server = TCPServer.new(host, port)
  server.close
  false
rescue Errno::EADDRINUSE
  true
end

.spawn_chromeObject



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/palapala/renderer.rb', line 151

def self.spawn_chrome
  return if port_in_use?
  return if chrome_process_healthy?

  # Define the path and parameters separately
  # chrome_path = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
  params = ["--headless", "--disable-gpu", "--remote-debugging-port=9222"]

  # Spawn the process with the path and parameters
  @chrome_process_id = Process.spawn(chrome_path, *params)

  # Wait until the port is in use
  until port_in_use?
    sleep 0.1
  end
  # Detach the process so it runs in the background
  Process.detach(@chrome_process_id)

  at_exit do
    if @chrome_process_id
      begin
        Process.kill("TERM", @chrome_process_id)
        Process.wait(@chrome_process_id)
        puts "Child process #{@chrome_process_id} terminated."
      rescue Errno::ESRCH
        puts "Child process #{@chrome_process_id} is already terminated."
      rescue Errno::ECHILD
        puts "No child process #{@chrome_process_id} found."
      end
    end
  end

  # Handle when the process is killed
  trap("SIGCHLD") do
    while (@chrome_process_id = Process.wait(-1, Process::WNOHANG))
      break if @chrome_process_id.nil?

      puts "Process #{@chrome_process_id} was killed."
      # Handle the error or restart the process if necessary
      @chrome_process_id = nil
    end
  rescue Errno::ECHILD
    @chrome_process_id = nil
  end
end