Skip to content

Instantly share code, notes, and snippets.

@jb55
Last active March 25, 2025 18:13
Show Gist options
  • Save jb55/dfcd7f67cb3d6d615c3a3035fd754016 to your computer and use it in GitHub Desktop.
Save jb55/dfcd7f67cb3d6d615c3a3035fd754016 to your computer and use it in GitHub Desktop.
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