use std::future::Future;
use std::pin::Pin;
use std::task::Context;
use std::task::Poll;
use super::channels::JobCancelSender;
use super::channels::JobResultReceiver;
use super::errors::JobHandleError;
use super::job_completion::JobCompletion;
use super::job_id::JobId;
#[derive(Debug)]
pub struct JobHandle {
job_id: JobId,
result_rx: JobResultReceiver,
cancel_tx: JobCancelSender,
}
impl JobHandle {
pub(super) fn new(
job_id: JobId,
result_rx: JobResultReceiver,
cancel_tx: JobCancelSender,
) -> Self {
Self {
job_id,
result_rx,
cancel_tx,
}
}
pub fn is_finished(&self) -> bool {
self.cancel_tx.is_closed()
}
pub fn cancel(&self) -> Result<(), JobHandleError> {
let result = self.cancel_tx.send(()).map_err(JobHandleError::from);
match result {
Ok(_) => tracing::debug!("Sent job-cancel msg to job: {}", self.job_id),
Err(ref e) => tracing::error!("{}", e),
};
result
}
pub fn job_id(&self) -> JobId {
self.job_id
}
}
impl Future for JobHandle {
type Output = Result<JobCompletion, JobHandleError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let result_rx = &mut self.get_mut().result_rx;
Pin::new(result_rx).poll(cx).map_err(|e| e.into())
}
}
impl Drop for JobHandle {
fn drop(&mut self) {
tracing::debug!("JobHandle dropping for job: {}", self.job_id);
if !self.cancel_tx.is_closed() {
let _ = self.cancel();
}
}
}