background-jobs/jobs-actix/src/actix_job.rs

50 lines
1.3 KiB
Rust
Raw Normal View History

2024-01-08 00:52:09 +00:00
use std::future::Future;
use background_jobs_core::{JoinError, UnsendSpawner};
2024-01-11 03:11:45 +00:00
use tokio::task::JoinHandle;
/// Provide a spawner for actix-based systems for Unsend Jobs
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2024-01-08 00:52:09 +00:00
pub struct ActixSpawner;
#[doc(hidden)]
2024-01-11 03:11:45 +00:00
pub struct ActixHandle<T>(Option<JoinHandle<T>>);
2024-01-08 00:52:09 +00:00
impl UnsendSpawner for ActixSpawner {
type Handle<T> = ActixHandle<T> where T: Send;
fn spawn<Fut>(future: Fut) -> Self::Handle<Fut::Output>
where
Fut: Future + 'static,
Fut::Output: Send + 'static,
{
2024-01-11 03:11:45 +00:00
ActixHandle(crate::spawn::spawn("job-task", future).ok())
2024-01-08 00:52:09 +00:00
}
}
impl<T> Unpin for ActixHandle<T> {}
impl<T> Future for ActixHandle<T> {
type Output = Result<T, JoinError>;
fn poll(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
2024-01-11 03:11:45 +00:00
if let Some(mut handle) = self.0.as_mut() {
let res = std::task::ready!(std::pin::Pin::new(&mut handle).poll(cx));
std::task::Poll::Ready(res.map_err(|_| JoinError))
} else {
std::task::Poll::Ready(Err(JoinError))
}
2024-01-08 00:52:09 +00:00
}
}
impl<T> Drop for ActixHandle<T> {
fn drop(&mut self) {
2024-01-11 03:11:45 +00:00
if let Some(handle) = &self.0 {
handle.abort();
}
2024-01-08 00:52:09 +00:00
}
}