diff --git a/lib/playwright/browser_type.ex b/lib/playwright/browser_type.ex index 70f190cf..03d81d0e 100644 --- a/lib/playwright/browser_type.ex +++ b/lib/playwright/browser_type.ex @@ -60,7 +60,7 @@ defmodule Playwright.BrowserType do end end - defp chromium(connection) do + def chromium(connection) do playwright = Channel.get(connection, {:guid, "Playwright"}) case playwright do diff --git a/lib/playwright_test/case.ex b/lib/playwright_test/case.ex index f5ec8f17..5d4205eb 100644 --- a/lib/playwright_test/case.ex +++ b/lib/playwright_test/case.ex @@ -44,7 +44,7 @@ defmodule PlaywrightTest.Case do """ defmacro __using__(options \\ %{}) do - quote do + quote location: :keep do alias Playwright.Runner.Config setup_all(context) do @@ -55,25 +55,32 @@ defmodule PlaywrightTest.Case do Application.put_env(:playwright, LaunchOptions, launch_options) {:ok, _} = Application.ensure_all_started(:playwright) - {connection, browser} = setup_browser(runner_options) - [browser: browser, connection: connection, transport: runner_options.transport] + browser_pool = PlaywrightTest.Pool.start_link() + + # {connection, browser} = setup_browser(runner_options) + # [browser: browser, connection: connection, transport: runner_options.transport] + [browser_pool: browser_pool, transport: runner_options.transport] end setup(context) do tagged_exclude = Map.get(context, :exclude, []) + connection = :poolboy.checkout(:playwright) + browser = Playwright.BrowserType.chromium(connection) + case Enum.member?(tagged_exclude, :page) do true -> - context + [browser: browser, connection: connection] false -> - page = Playwright.Browser.new_page(context.browser) + page = Playwright.Browser.new_page(browser) on_exit(:ok, fn -> Playwright.Page.close(page) end) Map.put(context, :page, page) + [page: page, browser: browser, connection: connection] end end diff --git a/lib/playwright_test/pool.ex b/lib/playwright_test/pool.ex new file mode 100644 index 00000000..acb2551f --- /dev/null +++ b/lib/playwright_test/pool.ex @@ -0,0 +1,45 @@ +defmodule PlaywrightTest.Pool do + @moduledoc false + + use GenServer + + def start_link(args \\ []) do + GenServer.start_link(__MODULE__, args, name: __MODULE__) + end + + def init(_args) do + pool_args = [ + name: {:local, :playwright}, + worker_module: Playwright.Runner.Connection, + size: 10, + max_overflow: 2 + ] + + worker_args = {Playwright.Runner.Transport.Driver, ["assets/node_modules/playwright/cli.js"]} + + case :poolboy.start_link(pool_args, worker_args) do + {:ok, browser_pool} -> browser_pool + {:error, {:already_started, browser_pool}} -> browser_pool + end + + {:ok, %{}} + end + + def checkout do + GenServer.call(__MODULE__, {:checkout, self()}) + end + + def handle_call({:checkout, pid}, _from, state) do + connection = :poolboy.checkout(:playwright) + browser = Playwright.BrowserType.chromium(connection) + + Process.monitor(pid) + {:reply, {connection, browser}, Map.put(state, pid, connection)} + end + + def handle_info({:DOWN, _ref, _type, pid, _reason}, state) do + {connection, state} = Map.pop(state, pid) + :poolboy.checkin(:playwright, connection) + {:noreply, state} + end +end diff --git a/mix.exs b/mix.exs index 8c382514..c75a1159 100644 --- a/mix.exs +++ b/mix.exs @@ -54,6 +54,7 @@ defmodule Playwright.MixProject do {:mix_audit, "~> 1.0", only: [:dev, :test], runtime: false}, {:plug_cowboy, "~> 2.5", only: [:dev, :test]}, {:plug, "~> 1.12", only: [:dev, :test]}, + {:poolboy, "~> 1.5"}, {:recase, "~> 0.7"}, {:uuid, "~> 1.1"} ] diff --git a/mix.lock b/mix.lock index 1a11f38a..a466fb42 100644 --- a/mix.lock +++ b/mix.lock @@ -21,6 +21,7 @@ "plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"}, "plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"}, "plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"}, + "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "recase": {:hex, :recase, "0.7.0", "3f2f719f0886c7a3b7fe469058ec539cb7bbe0023604ae3bce920e186305e5ae", [:mix], [], "hexpm", "36f5756a9f552f4a94b54a695870e32f4e72d5fad9c25e61bc4a3151c08a4e0c"}, "telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},