A fixed-size pool of reusable CDPEx.Browser processes.
Launching Chrome is expensive — a cold start can take several seconds on a constrained host, with a fresh profile each time. A pool keeps browsers warm and hands them out for reuse, so a per-job fetch no longer pays a launch on every call.
{:ok, pool} = CDPEx.Pool.start_link(size: 2, launch_opts: [headless: true])
CDPEx.Pool.with_page(pool, fn page ->
{:ok, _} = CDPEx.Page.navigate(page, "https://example.com")
CDPEx.Page.html(page)
end)Browsers are launched lazily up to :size and reused thereafter.
checkout/2 blocks (up to :checkout_timeout) when every browser is busy. The
pool is resilient: a caller that crashes while holding a browser has it returned
automatically, and a browser that crashes is dropped and relaunched on demand —
so :size self-heals. Put the pool under your supervision tree; its
terminate/2 stops every browser, reaping Chrome.
Browser launches are asynchronous — each cold start (a cold Chrome can take a
few seconds) runs in its own task, so the pool keeps serving checkouts, checkins,
and timeouts while browsers warm up, and a pool growing to :size under load
launches them concurrently. :checkout_timeout is honored even during warmup.
Options
:size— maximum number of browsers (default1):launch_opts— options passed to eachCDPEx.Browser(seeCDPEx.Chrome); any:ownerhere is ignored — the pool owns its browsers and sets it itself:checkout_timeout— ms to wait for a free browser (default5_000):name— registers the pool process
Summary
Functions
Returns a browser borrowed with checkout/2.
Borrows a browser, blocking up to timeout ms when all are busy.
Starts a pool. See the moduledoc for options.
Stops the pool, stopping every browser (and reaping Chrome).
Runs fun with a checked-out browser, returning it afterwards (even if fun
raises). Returns fun's value, or {:error, reason} if no browser was free.
Runs fun with a fresh page on a pooled browser, cleaning up the page and
returning the browser afterwards. The pooled counterpart of CDPEx.with_page/3
— it reuses a warm browser instead of launching one per call.
Types
Functions
@spec checkin(GenServer.server(), pid()) :: :ok
Returns a browser borrowed with checkout/2.
@spec checkout(GenServer.server(), timeout()) :: {:ok, pid()} | {:error, term()}
Borrows a browser, blocking up to timeout ms when all are busy.
Returns {:ok, browser}, {:error, :timeout}, or {:error, reason} if a
browser had to be launched and failed — a launch error is reported to a waiting
caller and is generally worth retrying. A caller still waiting when the pool stops
gets {:error, :noproc}. Always checkin/2 it when done — or use
with_browser/3 / with_page/3, which do that for you.
@spec start_link(keyword()) :: GenServer.on_start()
Starts a pool. See the moduledoc for options.
@spec stop(GenServer.server()) :: :ok
Stops the pool, stopping every browser (and reaping Chrome).
@spec with_browser(GenServer.server(), (pid() -> result), timeout()) :: result | {:error, term()} when result: var
Runs fun with a checked-out browser, returning it afterwards (even if fun
raises). Returns fun's value, or {:error, reason} if no browser was free.
@spec with_page(GenServer.server(), (CDPEx.Page.t() -> result), keyword()) :: result | {:error, term()} when result: var
Runs fun with a fresh page on a pooled browser, cleaning up the page and
returning the browser afterwards. The pooled counterpart of CDPEx.with_page/3
— it reuses a warm browser instead of launching one per call.
opts are forwarded to CDPEx.with_page/3 (e.g. :prevent_alerts); pass
:checkout_timeout to bound the wait for a free browser. Returns fun's value,
or {:error, reason}.