Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce PlaywrightManager helper module to stop using Fiber for Playwright #112

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ jobs:

- run: bundle install --jobs 4 --retry 3 --without "nmatrix python"

- run: bundle exec rake
- run: bundle exec rake VERBOSE=1
env:
TIMEOUT_SEC: 480

- run: rake build

Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/nmatrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ jobs:

- run: bundle install --jobs 4 --retry 3 --without "numo python"

- run: bundle exec rake
- run: bundle exec rake VERBOSE=1
env:
TIMEOUT_SEC: 480

- run: rake build

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/pycall.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ jobs:

- run: python -V

- run: bundle exec rake
- run: bundle exec rake VERBOSE=1
env:
PYTHON: python
TIMEOUT_SEC: 480
continue-on-error: ${{ matrix.python == '2.x' }}
4 changes: 3 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ require "rake/testtask"

desc "Run tests"
task :test do
ruby("test/run.rb")
verbose = ""
verbose = "-v" if ENV["VERBOSE"].to_i > 0
ruby("test/run.rb #{verbose}".strip)
end

task default: :test
63 changes: 63 additions & 0 deletions lib/charty/backends/backend_helpers/playwright_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
module Charty
module Backends
module BackendHelpers
module PlaywrightManager
@_playwright_exec = nil
@_browser = nil
@_context = nil

module_function def playwright
unless @_playwright_exec
load_playwright
path = ENV.fetch("PLAYWRIGHT_CLI_EXECUTABLE_PATH", "npx playwright")
@_playwright_exec = Playwright.create(playwright_cli_executable_path: path)
end
@_playwright_exec.playwright
end

module_function def launch_browser
playwright.chromium.launch(headless: true)
end

module_function def default_browser
unless @_browser
@_browser = launch_browser
end
@_browser
end

module_function def default_context
unless @_context
@_context = default_browser.new_context
end
@_context
end

module_function def new_page(&block)
page = default_context.new_page
return page unless block

begin
return block.call(page)
ensure
page.close
end
end

module_function def load_playwright
require "playwright"
rescue LoadError
$stderr.puts "ERROR: You need to install playwright and playwright-ruby-client before using Plotly renderer"
raise
end

module_function def shutdown
@_playwright_exec.stop if @_playwright_exec
@_playwright_exec = nil
@_context = nil
@_browser = nil
end
end
end
end
end
60 changes: 9 additions & 51 deletions lib/charty/backends/plotly.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require_relative "plotly_helpers/html_renderer"
require_relative "plotly_helpers/notebook_renderer"
require_relative "plotly_helpers/plotly_renderer"
require_relative "backend_helpers/playwright_manager"

module Charty
module Backends
Expand Down Expand Up @@ -918,60 +919,17 @@ def self.mathjax_config
end
end

@playwright_fiber = nil

def self.ensure_playwright
if @playwright_fiber.nil?
begin
require "playwright"
rescue LoadError
$stderr.puts "ERROR: You need to install playwright and playwright-ruby-client before using Plotly renderer"
raise
end
def self.render_image(input, output, format, element_id, width, height)
BackendHelpers::PlaywrightManager.new_page do |page|
page.set_viewport_size(width: width, height: height)
page.goto("file://#{input}")
element = page.query_selector("\##{element_id}")

@playwright_fiber = Fiber.new do
playwright_cli_executable_path = ENV.fetch("PLAYWRIGHT_CLI_EXECUTABLE_PATH", "npx playwright")
Playwright.create(playwright_cli_executable_path: playwright_cli_executable_path) do |playwright|
playwright.chromium.launch(headless: true) do |browser|
request = Fiber.yield
loop do
result = nil
case request.shift
when :finish
break
when :render
input, output, format, element_id, width, height = request

page = browser.new_page
page.set_viewport_size(width: width, height: height)
page.goto("file://#{input}")
element = page.query_selector("\##{element_id}")

kwargs = {type: format}
kwargs[:path] = output unless output.nil?
result = element.screenshot(**kwargs)
end
request = Fiber.yield(result)
end
end
end
end
@playwright_fiber.resume
kwargs = {type: format}
kwargs[:path] = output unless output.nil?
element.screenshot(**kwargs)
end
end

def self.terminate_playwright
return if @playwright_fiber.nil?

@playwright_fiber.resume([:finish])
end

at_exit { terminate_playwright }

def self.render_image(input, output, format, element_id, width, height)
ensure_playwright if @playwright_fiber.nil?
@playwright_fiber.resume([:render, input, output, format.to_s, element_id, width, height])
end
end
end
end
10 changes: 9 additions & 1 deletion test/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# $VERBOSE = true

require "pathname"
require "timeout"

base_dir = Pathname(__dir__).parent.expand_path

Expand All @@ -16,4 +17,11 @@

require_relative "helper"

exit(Test::Unit::AutoRunner.run(true, test_dir.to_s))
run_test = lambda { Test::Unit::AutoRunner.run(true, test_dir.to_s) }
timeout_sec = ENV.fetch("TIMEOUT_SEC", "0").to_i
status = if timeout_sec > 0
Timeout.timeout(timeout_sec) { run_test.() }
else
run_test.()
end
exit(status)
Loading