timerwheel 0.1.0

Hierarchical timer wheel for delayed task scheduling with pluggable executors.
Documentation
// Copyright © 2026-present The Timerwheel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::Arc;

use crate::error::{Error, Result};
use crate::executor::Pool;
use crate::executor::metric_sink::{MetricSink, NoopMetricSink};
use crate::executor::panic_handler::{NoopPanicHandler, PanicHandler};
use crate::policy::RejectPolicy;

/// Builder for the default bounded worker executor.
#[derive(Clone)]
pub struct PoolBuilder {
    pub(crate) workers: usize,
    pub(crate) queue_capacity: usize,
    pub(crate) reject_policy: RejectPolicy,
    pub(crate) panic_handler: Arc<dyn PanicHandler>,
    pub(crate) metric_sink: Arc<dyn MetricSink>,
}

impl Default for PoolBuilder {
    fn default() -> Self {
        Self {
            workers: std::thread::available_parallelism()
                .map(usize::from)
                .unwrap_or(1),
            queue_capacity: 100_000,
            reject_policy: RejectPolicy::Reject,
            panic_handler: Arc::new(NoopPanicHandler),
            metric_sink: Arc::new(NoopMetricSink),
        }
    }
}

impl PoolBuilder {
    /// Sets the number of worker threads.
    pub fn workers(mut self, workers: usize) -> Self {
        self.workers = workers;
        self
    }

    /// Sets the bounded task queue capacity.
    pub fn queue_capacity(mut self, queue_capacity: usize) -> Self {
        self.queue_capacity = queue_capacity;
        self
    }

    /// Sets how direct pool submissions behave when the queue is full.
    pub fn reject_policy(mut self, reject_policy: RejectPolicy) -> Self {
        self.reject_policy = reject_policy;
        self
    }

    /// Sets the panic observer called when worker task execution panics.
    pub fn panic_handler<H>(mut self, panic_handler: H) -> Self
    where
        H: PanicHandler,
    {
        self.panic_handler = Arc::new(panic_handler);
        self
    }

    /// Sets the metrics observer called after executor metric changes.
    pub fn metric_sink<S>(mut self, metric_sink: S) -> Self
    where
        S: MetricSink,
    {
        self.metric_sink = Arc::new(metric_sink);
        self
    }

    /// Builds the executor pool.
    pub fn build(self) -> Result<Pool> {
        if self.workers == 0 {
            return Err(Error::InvalidConfig("workers must be greater than zero"));
        }
        if self.queue_capacity == 0 {
            return Err(Error::InvalidConfig(
                "queue_capacity must be greater than zero",
            ));
        }

        Pool::new(self)
    }
}