vectordb/src/thread.rs
2023-07-04 17:39:17 -05:00

59 lines
1.4 KiB
Rust

use std::panic::AssertUnwindSafe;
#[derive(Debug)]
pub(super) struct Thread {
handle: AssertUnwindSafe<Option<std::thread::JoinHandle<()>>>,
stopper: flume::Sender<()>,
}
pub(super) struct ThreadBuilder {
name: String,
}
impl ThreadBuilder {
pub(super) fn spawn<F>(self, func: F) -> Thread
where
F: FnOnce(flume::Receiver<()>) + Send + 'static,
{
let (stopper, rx) = flume::bounded(1);
let handle = AssertUnwindSafe(Some(
std::thread::Builder::new()
.name(self.name)
.spawn(move || (func)(rx))
.expect("Spawned thread"),
));
Thread { handle, stopper }
}
}
impl Thread {
pub(super) fn build(name: String) -> ThreadBuilder {
ThreadBuilder { name }
}
pub(super) fn shutdown(mut self) -> Result<(), Box<dyn std::any::Any + Send + 'static>> {
self.do_shutdown()
}
pub(super) fn cancel(&self) -> bool {
self.stopper.try_send(()).is_ok()
}
fn do_shutdown(&mut self) -> Result<(), Box<dyn std::any::Any + Send + 'static>> {
let _ = self.stopper.send(());
if let Some(handle) = self.handle.take() {
handle.join()
} else {
Ok(())
}
}
}
impl Drop for Thread {
fn drop(&mut self) {
self.do_shutdown().expect("Panick in dropped thread");
}
}