use std::{
thread,
time::Duration,
};
use super::{
BlockingExecutorService,
BlockingExecutorServiceBuilder,
ExecutionServices,
ExecutionServicesBuildError,
RayonExecutorService,
RayonExecutorServiceBuilder,
TokioBlockingExecutorService,
TokioIoExecutorService,
};
#[derive(Debug, Clone)]
pub struct ExecutionServicesBuilder {
blocking: BlockingExecutorServiceBuilder,
cpu: RayonExecutorServiceBuilder,
}
impl ExecutionServicesBuilder {
#[inline]
pub fn blocking_pool_size(mut self, pool_size: usize) -> Self {
self.blocking = self.blocking.pool_size(pool_size);
self
}
#[inline]
pub fn blocking_core_pool_size(mut self, core_pool_size: usize) -> Self {
self.blocking = self.blocking.core_pool_size(core_pool_size);
self
}
#[inline]
pub fn blocking_maximum_pool_size(mut self, maximum_pool_size: usize) -> Self {
self.blocking = self.blocking.maximum_pool_size(maximum_pool_size);
self
}
#[inline]
pub fn blocking_queue_capacity(mut self, capacity: usize) -> Self {
self.blocking = self.blocking.queue_capacity(capacity);
self
}
#[inline]
pub fn blocking_unbounded_queue(mut self) -> Self {
self.blocking = self.blocking.unbounded_queue();
self
}
#[inline]
pub fn blocking_thread_name_prefix(mut self, prefix: &str) -> Self {
self.blocking = self.blocking.thread_name_prefix(prefix);
self
}
#[inline]
pub fn blocking_stack_size(mut self, stack_size: usize) -> Self {
self.blocking = self.blocking.stack_size(stack_size);
self
}
#[inline]
pub fn blocking_keep_alive(mut self, keep_alive: Duration) -> Self {
self.blocking = self.blocking.keep_alive(keep_alive);
self
}
#[inline]
pub fn blocking_allow_core_thread_timeout(mut self, allow: bool) -> Self {
self.blocking = self.blocking.allow_core_thread_timeout(allow);
self
}
#[inline]
pub fn blocking_prestart_core_threads(mut self) -> Self {
self.blocking = self.blocking.prestart_core_threads();
self
}
#[inline]
pub fn cpu_threads(mut self, num_threads: usize) -> Self {
self.cpu = self.cpu.num_threads(num_threads);
self
}
#[inline]
pub fn cpu_thread_name_prefix(mut self, prefix: &str) -> Self {
self.cpu = self.cpu.thread_name_prefix(prefix);
self
}
#[inline]
pub fn cpu_stack_size(mut self, stack_size: usize) -> Self {
self.cpu = self.cpu.stack_size(stack_size);
self
}
pub fn build(self) -> Result<ExecutionServices, ExecutionServicesBuildError> {
let blocking = self
.blocking
.build()
.map_err(|source| ExecutionServicesBuildError::Blocking { source })?;
let cpu = self
.cpu
.build()
.map_err(|source| ExecutionServicesBuildError::Cpu { source })?;
let tokio_blocking = TokioBlockingExecutorService::new();
let io = TokioIoExecutorService::new();
Ok(ExecutionServices::from_parts(
blocking,
cpu,
tokio_blocking,
io,
))
}
}
impl Default for ExecutionServicesBuilder {
fn default() -> Self {
let pool_size = default_pool_size();
Self {
blocking: BlockingExecutorService::builder().pool_size(pool_size),
cpu: RayonExecutorService::builder().num_threads(pool_size),
}
}
}
fn default_pool_size() -> usize {
thread::available_parallelism()
.map(usize::from)
.unwrap_or(1)
}