pub struct BrowserPool { /* private fields */ }Expand description
Main browser pool with lifecycle management.
This is the public-facing API for the browser pool. It wraps the internal state and manages the keep-alive thread.
§Overview
BrowserPool provides:
- Browser checkout via
get() - Pool warmup via
warmup() - Statistics via
stats() - Graceful shutdown via
shutdown_async()
§Example
use html2pdf_api::{BrowserPool, BrowserPoolConfigBuilder, ChromeBrowserFactory};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create pool
let mut pool = BrowserPool::builder()
.config(
BrowserPoolConfigBuilder::new()
.max_pool_size(5)
.warmup_count(3)
.build()?
)
.factory(Box::new(ChromeBrowserFactory::with_defaults()))
.build()?;
// Warmup
pool.warmup().await?;
// Use browsers
{
let browser = pool.get()?;
let tab = browser.new_tab()?;
// ... do work ...
} // browser returned to pool automatically
// Shutdown
pool.shutdown_async().await;
Ok(())
}§Thread Safety
BrowserPool is Send and can be wrapped in Arc<Mutex<>> for sharing
across threads. Use into_shared() for convenience.
Implementations§
Source§impl BrowserPool
impl BrowserPool
Convert pool into a shared Arc<Mutex<>> for use in web handlers.
This is convenient for web frameworks that need shared state.
§Example
let pool = BrowserPool::builder()
.factory(Box::new(ChromeBrowserFactory::with_defaults()))
.build()?
.into_shared();
// Can now be cloned and shared across handlers
let pool_clone = Arc::clone(&pool);Sourcepub fn builder() -> BrowserPoolBuilder
pub fn builder() -> BrowserPoolBuilder
Sourcepub fn get(&self) -> Result<BrowserHandle>
pub fn get(&self) -> Result<BrowserHandle>
Get a browser from the pool (or create one if empty).
Returns a BrowserHandle that implements Deref<Target=Browser>,
allowing transparent access to browser methods.
§Automatic Return
The browser is automatically returned to the pool when the handle is dropped, even if your code panics (RAII pattern).
§Errors
- Returns
BrowserPoolError::ShuttingDownif pool is shutting down. - Returns
BrowserPoolError::BrowserCreationif new browser creation fails. - Returns
BrowserPoolError::HealthCheckFailedif all pooled browsers are unhealthy.
§Example
let browser = pool.get()?;
let tab = browser.new_tab()?;
tab.navigate_to("https://example.com")?;
// browser returned automatically when it goes out of scopeSourcepub fn stats(&self) -> PoolStats
pub fn stats(&self) -> PoolStats
Get pool statistics snapshot.
§Returns
PoolStats containing:
available: Browsers in pool ready for checkoutactive: All browsers (pooled + checked out)total: Currently same asactive(for future expansion)
§Example
let stats = pool.stats();
println!("Available: {}, Active: {}", stats.available, stats.active);Sourcepub fn config(&self) -> &BrowserPoolConfig
pub fn config(&self) -> &BrowserPoolConfig
Get a reference to the pool configuration.
Returns the configuration that was used to create this pool. The configuration is immutable after pool creation.
§Example
let pool = BrowserPool::builder()
.config(
BrowserPoolConfigBuilder::new()
.max_pool_size(10)
.build()?
)
.factory(Box::new(ChromeBrowserFactory::with_defaults()))
.build()?;
println!("Max pool size: {}", pool.config().max_pool_size);
println!("Browser TTL: {:?}", pool.config().browser_ttl);§Use Cases
- Logging configuration at startup
- Monitoring/metrics collection
- Readiness checks (comparing active count vs max_pool_size)
- Debugging pool behavior
Sourcepub async fn warmup(&self) -> Result<()>
pub async fn warmup(&self) -> Result<()>
Warmup the pool by pre-creating browsers.
This is highly recommended to reduce first-request latency. Should be called during application startup.
§Process
- Creates
warmup_countbrowsers sequentially with staggered timing - Tests each browser with navigation
- Returns all browsers to pool
- Entire process has timeout (configurable via
warmup_timeout)
§Staggered Creation
Browsers are created with a 30-second delay between them to ensure their TTLs are offset. This prevents all browsers from expiring at the same time.
§Errors
- Returns error if warmup times out.
- Returns error if browser creation fails.
§Example
let pool = BrowserPool::builder()
.factory(Box::new(ChromeBrowserFactory::with_defaults()))
.build()?;
// Warmup during startup
pool.warmup().await?;Sourcepub async fn shutdown_async(&mut self)
pub async fn shutdown_async(&mut self)
Asynchronously shutdown the pool (recommended method).
This is the preferred shutdown method as it can properly await async task cancellation. Should be called during application shutdown.
§Shutdown Process
- Set atomic shutdown flag (stops new operations)
- Signal condvar to wake keep-alive thread immediately
- Wait for keep-alive thread to exit (with timeout)
- Abort all replacement creation tasks
- Wait briefly for cleanup
- Log final statistics
§Timeout
Keep-alive thread is given 5 seconds to exit gracefully. If it doesn’t exit, we log an error but continue shutdown.
§Example
let mut pool = /* ... */;
// During application shutdown
pool.shutdown_async().await;Sourcepub fn shutdown(&mut self)
pub fn shutdown(&mut self)
Synchronously shutdown the pool (fallback method).
This is a simplified shutdown for use in Drop or non-async contexts.
Prefer shutdown_async() when possible for cleaner task cancellation.
§Note
This method doesn’t wait for replacement tasks to finish since there’s no async runtime available. Tasks are aborted but may not have cleaned up yet.
Trait Implementations§
Source§impl BrowserPoolActixExt for BrowserPool
impl BrowserPoolActixExt for BrowserPool
Source§fn into_actix_data(self) -> BrowserPoolData
fn into_actix_data(self) -> BrowserPoolData
Data wrapper. Read moreSource§impl BrowserPoolAxumExt for BrowserPool
impl BrowserPoolAxumExt for BrowserPool
Source§fn into_axum_state(self) -> SharedBrowserPool
fn into_axum_state(self) -> SharedBrowserPool
with_state(). Read moreSource§fn into_axum_extension(self) -> Extension<SharedBrowserPool>
fn into_axum_extension(self) -> Extension<SharedBrowserPool>
Source§impl BrowserPoolRocketExt for BrowserPool
impl BrowserPoolRocketExt for BrowserPool
Source§fn into_rocket_data(self) -> SharedBrowserPool
fn into_rocket_data(self) -> SharedBrowserPool
Auto Trait Implementations§
impl Freeze for BrowserPool
impl !RefUnwindSafe for BrowserPool
impl Send for BrowserPool
impl Sync for BrowserPool
impl Unpin for BrowserPool
impl !UnwindSafe for BrowserPool
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoCollection<T> for T
impl<T> IntoCollection<T> for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);