pub struct TaskExecutionService { /* private fields */ }Expand description
Managed task execution service built on ThreadPool.
Assigns a stable business TaskId per task and tracks service-level status
(submitted, running, succeeded, failed, cancelled, panicked). The typed task
outcome is still retrieved through TaskHandle.
§Responsibilities
- Registry: The same
TaskIdcannot be submitted again while a record for it exists; a duplicate returnsTaskExecutionServiceError::DuplicateTask. Use this when you need lookup by ID, optional pre-start cancellation, or long-lived task bookkeeping. - Thread pool: Owns a
ThreadPoolfor queuing and worker threads; queue internals are not exposed. Configure the pool viaTaskExecutionServiceBuilderorSelf::builder. - Submission semantics:
Self::submit/Self::submit_callablereturningOk(handle)means only that the service accepted the task—not that it started or succeeded. Observe the final result withTaskHandle::getor by awaiting the handle’sFutureimplementation.
§Suspend
Self::suspend rejects new submissions (TaskExecutionServiceError::Suspended).
Tasks already queued or running are unaffected. Self::resume re-enables submission.
§Cancel
Self::cancel may succeed only before the task starts running; once running,
cancellation behavior follows TaskHandle and the internal completion protocol.
§Shutdown
Self::shutdown and Self::stop delegate to the backing pool.
Self::wait_termination blocks the current thread until all accepted work
has completed, failed, panicked, or been cancelled.
§Example: submit, inspect status, wait for idle, shutdown
use std::error::Error;
use qubit_task::service::{TaskExecutionService, TaskId, TaskStatus};
fn main() -> Result<(), Box<dyn Error>> {
let service = TaskExecutionService::new()?;
let id: TaskId = 1001;
let handle = service.submit(id, || Ok::<(), ()>(()))?;
handle.get().unwrap();
assert_eq!(service.status(id), Some(TaskStatus::Succeeded));
service.await_idle();
service.shutdown();
Ok(())
}Implementations§
Source§impl TaskExecutionService
impl TaskExecutionService
Sourcepub fn new() -> Result<Self, ExecutorServiceBuilderError>
pub fn new() -> Result<Self, ExecutorServiceBuilderError>
Creates a service using the default super::ThreadPoolBuilder settings (worker
counts, queue, and other defaults match ThreadPool::builder).
§Example
use qubit_task::service::{TaskExecutionService, ExecutorServiceBuilderError};
fn main() -> Result<(), ExecutorServiceBuilderError> {
let _service = TaskExecutionService::new()?;
Ok(())
}§Returns
Ok(Self) on success, or ExecutorServiceBuilderError if the pool cannot be built.
Sourcepub fn builder() -> TaskExecutionServiceBuilder
pub fn builder() -> TaskExecutionServiceBuilder
Returns a TaskExecutionServiceBuilder so you can tune the backing pool
before TaskExecutionServiceBuilder::build (for example
super::ThreadPoolBuilder::pool_size,
super::ThreadPoolBuilder::queue_capacity).
§Example
use qubit_task::service::{
TaskExecutionService, ThreadPoolBuilder, ExecutorServiceBuilderError,
};
fn main() -> Result<(), ExecutorServiceBuilderError> {
let _service = TaskExecutionService::builder()
.thread_pool(ThreadPoolBuilder::default().pool_size(8))
.build()?;
Ok(())
}§Returns
A builder holding the default super::ThreadPoolBuilder.
Sourcepub fn submit<T, E>(
&self,
task_id: TaskId,
task: T,
) -> Result<TaskHandle<(), E>, TaskExecutionServiceError>
pub fn submit<T, E>( &self, task_id: TaskId, task: T, ) -> Result<TaskHandle<(), E>, TaskExecutionServiceError>
Submits a runnable task with a business task ID.
§Example
use std::error::Error;
use qubit_task::service::TaskExecutionService;
fn main() -> Result<(), Box<dyn Error>> {
let service = TaskExecutionService::new()?;
let handle = service.submit(42_u64, || Ok::<(), ()>(()))?;
handle.get().unwrap();
Ok(())
}§Parameters
task_id- Stable business ID for registry operations.task- Runnable to execute.
§Returns
Ok(handle) if the service accepts the task. This only means
acceptance; task success is observed through the handle. Returns
TaskExecutionServiceError when the ID is duplicated, the service is
suspended, or the backing pool rejects the task.
Sourcepub fn submit_callable<C, R, E>(
&self,
task_id: TaskId,
task: C,
) -> Result<TaskHandle<R, E>, TaskExecutionServiceError>
pub fn submit_callable<C, R, E>( &self, task_id: TaskId, task: C, ) -> Result<TaskHandle<R, E>, TaskExecutionServiceError>
Submits a callable task with a business task ID.
§Example
use std::error::Error;
use qubit_task::service::{TaskExecutionService, TaskId};
fn main() -> Result<(), Box<dyn Error>> {
let service = TaskExecutionService::new()?;
let id: TaskId = 7;
let handle = service.submit_callable(id, || Ok::<i32, ()>(21))?;
assert_eq!(handle.get().unwrap(), 21);
Ok(())
}§Parameters
task_id- Stable business ID for registry operations.task- Callable to execute.
§Returns
Ok(handle) if the service accepts the task. The handle reports the
typed task result while this service records only service-level status.
Sourcepub fn cancel(&self, task_id: TaskId) -> bool
pub fn cancel(&self, task_id: TaskId) -> bool
Attempts to cancel a submitted task by ID.
Cancellation succeeds only before the task starts running.
§Example
use std::error::Error;
use qubit_task::service::{TaskExecutionService, TaskId};
fn main() -> Result<(), Box<dyn Error>> {
let service = TaskExecutionService::new()?;
let id: TaskId = 1;
let handle = service.submit(id, || Ok::<(), ()>(()))?;
// `true` only if cancelled before a worker starts the task (race with the pool).
let _cancelled = service.cancel(id);
match handle.get() {
Ok(()) => {}
Err(e) if e.is_cancelled() => {}
Err(e) => panic!("unexpected task outcome: {e:?}"),
}
Ok(())
}§Parameters
task_id- ID of the task to cancel.
§Returns
true if the task was cancelled before start, or false if no active
task with this ID can be cancelled.
Sourcepub fn status(&self, task_id: TaskId) -> Option<TaskStatus>
pub fn status(&self, task_id: TaskId) -> Option<TaskStatus>
Returns the current status of a task.
§Example
use std::error::Error;
use qubit_task::service::{TaskExecutionService, TaskId, TaskStatus};
fn main() -> Result<(), Box<dyn Error>> {
let service = TaskExecutionService::new()?;
let id: TaskId = 10;
let handle = service.submit(id, || Ok::<(), ()>(()))?;
handle.get().unwrap();
assert_eq!(service.status(id), Some(TaskStatus::Succeeded));
Ok(())
}§Parameters
task_id- ID of the task to inspect.
§Returns
Some(status) if the service retains a record for this ID, or None
if the ID is unknown.
Sourcepub fn stats(&self) -> TaskExecutionStats
pub fn stats(&self) -> TaskExecutionStats
Returns registry-derived task statistics.
§Example
use std::error::Error;
use qubit_task::service::TaskExecutionService;
fn main() -> Result<(), Box<dyn Error>> {
let service = TaskExecutionService::new()?;
let handle = service.submit(1_u64, || Ok::<(), ()>(()))?;
handle.get().unwrap();
let snapshot = service.stats();
assert!(snapshot.total >= 1);
Ok(())
}§Returns
A snapshot of retained task records grouped by status.
Sourcepub fn suspend(&self)
pub fn suspend(&self)
Suspends new submissions.
Existing submitted and running tasks continue normally.
§Example
use qubit_task::service::{TaskExecutionService, ExecutorServiceBuilderError};
fn main() -> Result<(), ExecutorServiceBuilderError> {
let service = TaskExecutionService::new()?;
service.suspend();
assert!(service.is_suspended());
service.resume();
assert!(!service.is_suspended());
Ok(())
}Sourcepub fn is_suspended(&self) -> bool
pub fn is_suspended(&self) -> bool
Returns whether the service is suspended.
§Returns
true if new submissions are rejected before reaching the pool.
Sourcepub fn await_in_flight_tasks_completion(&self)
pub fn await_in_flight_tasks_completion(&self)
Waits for the active task snapshot observed at call time to finish.
Tasks submitted after this method starts are not part of the waited snapshot. This method blocks the current thread.
§Example
use std::error::Error;
use qubit_task::service::{TaskExecutionService, TaskId};
fn main() -> Result<(), Box<dyn Error>> {
let service = TaskExecutionService::new()?;
let a: TaskId = 1;
let b: TaskId = 2;
let h1 = service.submit(a, || Ok::<(), ()>(()))?;
let h2 = service.submit(b, || Ok::<(), ()>(()))?;
service.await_in_flight_tasks_completion();
h1.get().unwrap();
h2.get().unwrap();
Ok(())
}Sourcepub fn await_idle(&self)
pub fn await_idle(&self)
Waits until the service registry has no submitted or running tasks.
This method blocks the current thread and observes real-time idleness.
§Example
use std::error::Error;
use qubit_task::service::{TaskExecutionService, TaskId};
fn main() -> Result<(), Box<dyn Error>> {
let service = TaskExecutionService::new()?;
let id: TaskId = 1;
let handle = service.submit(id, || Ok::<(), ()>(()))?;
handle.get().unwrap();
service.await_idle();
Ok(())
}Sourcepub fn shutdown(&self)
pub fn shutdown(&self)
Initiates graceful shutdown of the backing pool.
§Example
use qubit_task::service::{TaskExecutionService, ExecutorServiceBuilderError};
fn main() -> Result<(), ExecutorServiceBuilderError> {
let service = TaskExecutionService::new()?;
service.shutdown();
assert!(service.is_not_running());
Ok(())
}Sourcepub fn stop(&self) -> StopReport
pub fn stop(&self) -> StopReport
Initiates immediate stop of the backing pool.
§Example
use qubit_task::service::{TaskExecutionService, ExecutorServiceBuilderError};
fn main() -> Result<(), ExecutorServiceBuilderError> {
let service = TaskExecutionService::new()?;
let _report = service.stop();
Ok(())
}§Returns
A count-based report from the backing pool.
Sourcepub fn is_not_running(&self) -> bool
pub fn is_not_running(&self) -> bool
Returns whether the backing pool no longer accepts new work.
Sourcepub fn is_terminated(&self) -> bool
pub fn is_terminated(&self) -> bool
Returns whether the backing pool has terminated.
Sourcepub fn wait_termination(&self)
pub fn wait_termination(&self)
Blocks until the backing pool has terminated.
§Example
use qubit_task::service::{TaskExecutionService, ExecutorServiceBuilderError};
fn main() -> Result<(), ExecutorServiceBuilderError> {
let service = TaskExecutionService::new()?;
service.shutdown();
service.wait_termination();
assert!(service.is_terminated());
Ok(())
}§Returns
Returns after shutdown and worker exit.
Sourcepub fn thread_pool(&self) -> &ThreadPool
pub fn thread_pool(&self) -> &ThreadPool
Returns the backing thread pool.
§Example
use qubit_task::service::{TaskExecutionService, ExecutorServiceBuilderError};
fn main() -> Result<(), ExecutorServiceBuilderError> {
let service = TaskExecutionService::new()?;
let pool = service.thread_pool();
assert!(pool.maximum_pool_size() > 0);
Ok(())
}§Returns
A shared reference for low-level inspection such as pool statistics.