qubit_thread_pool/thread_pool/thread_pool_build_error.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use std::io;
11
12use thiserror::Error;
13
14use qubit_executor::service::RejectedExecution;
15
16/// Error returned when a [`super::thread_pool::ThreadPool`] cannot be built.
17///
18#[derive(Debug, Error)]
19pub enum ThreadPoolBuildError {
20 /// The configured maximum pool size is zero.
21 #[error("thread pool maximum pool size must be greater than zero")]
22 ZeroMaximumPoolSize,
23
24 /// The configured core pool size is greater than the maximum pool size.
25 #[error(
26 "thread pool core pool size {core_pool_size} exceeds maximum pool size {maximum_pool_size}"
27 )]
28 CorePoolSizeExceedsMaximum {
29 /// Configured core pool size.
30 core_pool_size: usize,
31
32 /// Configured maximum pool size.
33 maximum_pool_size: usize,
34 },
35
36 /// The configured bounded queue capacity is zero.
37 #[error("thread pool queue capacity must be greater than zero")]
38 ZeroQueueCapacity,
39
40 /// The configured worker stack size is zero.
41 #[error("thread pool stack size must be greater than zero")]
42 ZeroStackSize,
43
44 /// The configured keep-alive timeout is zero.
45 #[error("thread pool keep-alive timeout must be greater than zero")]
46 ZeroKeepAlive,
47
48 /// A worker thread could not be spawned.
49 #[error("failed to spawn thread pool worker {index}: {source}")]
50 SpawnWorker {
51 /// Index of the worker that failed to spawn.
52 index: usize,
53
54 /// I/O error reported by [`std::thread::Builder::spawn`].
55 source: io::Error,
56 },
57}
58
59impl ThreadPoolBuildError {
60 /// Converts a runtime worker-spawn rejection into a build error.
61 ///
62 /// # Parameters
63 ///
64 /// * `error` - Rejection produced while prestarting workers during build.
65 ///
66 /// # Returns
67 ///
68 /// A build error carrying equivalent failure context.
69 pub(crate) fn from_rejected_execution(error: RejectedExecution) -> Self {
70 match error {
71 RejectedExecution::WorkerSpawnFailed { source } => Self::SpawnWorker {
72 index: 0,
73 source: io::Error::new(source.kind(), source.to_string()),
74 },
75 RejectedExecution::Shutdown => Self::SpawnWorker {
76 index: 0,
77 source: io::Error::other("thread pool shut down during prestart"),
78 },
79 RejectedExecution::Saturated => Self::SpawnWorker {
80 index: 0,
81 source: io::Error::other("thread pool saturated during prestart"),
82 },
83 }
84 }
85}
86
87impl From<RejectedExecution> for ThreadPoolBuildError {
88 /// Converts rejected-execution reasons into build-time thread-pool errors.
89 ///
90 /// # Parameters
91 ///
92 /// * `error` - Rejection reason observed during thread prestart.
93 ///
94 /// # Returns
95 ///
96 /// A build error that preserves equivalent failure context.
97 fn from(error: RejectedExecution) -> Self {
98 Self::from_rejected_execution(error)
99 }
100}