maycoon_core/tasks/
runner.rs

1use crate::tasks::{TaskHandle, RUNNER};
2use futures::executor::{ThreadPool, ThreadPoolBuilder};
3use futures::task::SpawnExt;
4use std::future::Future;
5use std::num::NonZeroUsize;
6
7/// The Maycoon Task Runner for running asynchronous tasks using a thread pool from the [futures] crate.
8///
9/// Initialize it using the [TaskConfig](crate::config::TasksConfig) inside the [MayConfig](crate::config::MayConfig).
10pub struct TaskRunner {
11    pool: ThreadPool,
12}
13
14impl TaskRunner {
15    /// Creates a new [TaskRunner] with the given thread stack size and worker/thread count.
16    pub fn new(stack_size: usize, workers: NonZeroUsize) -> Result<Self, futures::io::Error> {
17        Ok(Self {
18            pool: ThreadPoolBuilder::new()
19                .stack_size(stack_size)
20                .pool_size(workers.get())
21                .name_prefix("maycoon-worker-")
22                .create()?,
23        })
24    }
25
26    /// Runs the given [Future] on the task runner thread pool and returns the output.
27    pub fn run<Fut>(&self, fut: Fut) -> TaskHandle<Fut::Output>
28    where
29        Fut: Future + Send + 'static,
30        Fut::Output: Send,
31    {
32        self.pool
33            .spawn_with_handle(fut)
34            .expect("Failed to spawn task")
35    }
36
37    /// Initialize the global task runner. This cannot be called twice. Will return [None] if the task runner is already initialized.
38    pub fn init(self) -> Option<()> {
39        RUNNER.set(self).ok()
40    }
41}