Last active
March 25, 2025 18:13
-
-
Save jb55/dfcd7f67cb3d6d615c3a3035fd754016 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::sync::mpsc::{self, Sender}; | |
use tokio::sync::oneshot; | |
use futures::Future; | |
// A trivial job type | |
type Job = Box<dyn FnOnce() -> String + Send>; | |
// A “synchronous” pool that receives jobs | |
struct JobPool { | |
tx: Sender<(Job, oneshot::Sender<String>)>, | |
} | |
impl JobPool { | |
// Spawns some worker threads on creation | |
fn new(num_threads: usize) -> Self { | |
let (tx, rx) = mpsc::channel::<(Job, oneshot::Sender<String>)>(); | |
for _ in 0..num_threads { | |
let rx_clone = rx.clone(); | |
std::thread::spawn(move || { | |
while let Ok((job, result_tx)) = rx_clone.recv() { | |
let output = job(); | |
let _ = result_tx.send(output); // ignore errors if receiver dropped | |
} | |
}); | |
} | |
JobPool { tx } | |
} | |
// Schedules a job and returns a Future that resolves when the job is done. | |
fn schedule(&self, job: Job) -> impl Future<Output = String> { | |
// oneshot to signal back to the async side | |
let (tx_result, rx_result) = oneshot::channel::<String>(); | |
// Send the job + channel into the threadpool | |
// If the pool is fully saturated, this call will block | |
// (you could swap out for a non-blocking channel if needed) | |
self.tx.send((job, tx_result)).unwrap(); | |
// Return a Future that waits for the job’s result | |
async move { | |
match rx_result.await { | |
Ok(res) => res, | |
Err(_) => "Worker thread or channel dropped?".to_string(), | |
} | |
} | |
} | |
} | |
// Example usage from async code | |
#[tokio::main] | |
async fn main() { | |
// Create your dedicated threadpool for heavy tasks | |
let job_pool = JobPool::new(2); | |
// In your async flow, schedule a CPU-heavy job | |
let job_future = job_pool.schedule(Box::new(|| { | |
// CPU-intensive job here | |
// e.g., decode a WebP or parse a big file | |
"Result of heavy job".to_string() | |
})); | |
// Meanwhile, do other async stuff... | |
println!("Async code continues..."); | |
// Then await the heavy job | |
let result = job_future.await; | |
println!("Got result: {}", result); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment