Skip to content
Closed
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
43 changes: 43 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,28 @@ pub struct Config {

/// Background color as RGBA (default: white).
pub background: [u8; 4],

/// Number of threads stylo uses for parallel style traversal.
///
/// - `None` (default): use blitz's auto heuristic
/// (`num_cpus * 3/4`, capped at 6).
/// - `Some(1)`: disable parallel traversal. Style work runs serially
/// on the calling thread.
/// - `Some(n)` with `n >= 2`: use a pool of `n` worker threads.
///
/// Set this to `Some(1)` when calling `render` concurrently from
/// multiple OS threads (e.g. a server rendering one document per
/// request via `tokio::task::spawn_blocking`). Stylo's
/// `STYLE_THREAD_POOL` is process-global; two parallel traversals
/// landing on the same rayon worker both try to mutably borrow the
/// worker's thread-local sharing cache and one panics. Disabling
/// parallelism keeps each render's stylo work on the caller's OS
/// thread, where the thread-local is uniquely owned.
///
/// **One-shot:** stylo's `STYLE_THREAD_POOL` is initialised on first
/// access. The value set on the first `render(...)` call in the
/// process wins; later calls inherit that pool size regardless.
pub style_thread_count: Option<i32>,
}

impl Default for Config {
Expand All @@ -94,6 +116,7 @@ impl Default for Config {
color_scheme: ColorScheme::Light,
auto_height: false,
background: [255, 255, 255, 255], // White
style_thread_count: None,
}
}
}
Expand Down Expand Up @@ -248,6 +271,26 @@ impl Config {
self.background([0, 0, 0, 0])
}

/// Configure stylo's parallel style-traversal thread count.
///
/// Pass `1` to disable parallel traversal when calling `render`
/// concurrently from multiple OS threads. See the field-level
/// docs on [`Config::style_thread_count`] for the full rationale.
///
/// # Example
///
/// ```rust
/// use hyper_render::Config;
///
/// // Server context: one render per `spawn_blocking` thread.
/// let config = Config::new().style_thread_count(1);
/// assert_eq!(config.style_thread_count, Some(1));
/// ```
pub fn style_thread_count(mut self, count: i32) -> Self {
self.style_thread_count = Some(count);
self
}

/// Minimum supported width/height in pixels.
///
/// Very small dimensions can cause overflow issues in the underlying
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ fn create_document(html: &str, config: &Config) -> Result<HtmlDocument> {

let doc_config = DocumentConfig {
viewport: Some(viewport),
stylo_thread_count: config.style_thread_count,
..Default::default()
};

Expand Down