Add job handle to jobs to wait for results
Signed-off-by: trivernis <trivernis@protonmail.com>feature/jobs
parent
a87c341867
commit
e9dbbd1bd5
@ -0,0 +1,102 @@
|
||||
use mediarepo_core::error::{RepoError, RepoResult};
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::broadcast::{Receiver, Sender};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub struct JobHandle<T: Send + Sync, R: Send + Sync> {
|
||||
status: Arc<RwLock<T>>,
|
||||
state: Arc<RwLock<JobState>>,
|
||||
result_receiver: CloneableReceiver<Arc<RwLock<RepoResult<R>>>>,
|
||||
}
|
||||
|
||||
impl<T: Send + Sync, R: Send + Sync> Clone for JobHandle<T, R> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
status: self.status.clone(),
|
||||
state: self.state.clone(),
|
||||
result_receiver: self.result_receiver.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Send + Sync, R: Send + Sync> JobHandle<T, R> {
|
||||
pub fn new(
|
||||
status: Arc<RwLock<T>>,
|
||||
state: Arc<RwLock<JobState>>,
|
||||
result_receiver: CloneableReceiver<Arc<RwLock<RepoResult<R>>>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
status,
|
||||
state,
|
||||
result_receiver,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn state(&self) -> JobState {
|
||||
*self.state.read().await
|
||||
}
|
||||
|
||||
pub fn status(&self) -> &Arc<RwLock<T>> {
|
||||
&self.status
|
||||
}
|
||||
|
||||
pub async fn result(&mut self) -> Arc<RwLock<RepoResult<R>>> {
|
||||
match self.result_receiver.recv().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => Arc::new(RwLock::new(Err(RepoError::from(&*e.to_string())))),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn try_result(&mut self) -> RepoResult<R> {
|
||||
let shared_result = self.result().await;
|
||||
let mut result = shared_result.write().await;
|
||||
mem::replace(&mut *result, Err(RepoError::from("result taken")))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub enum JobState {
|
||||
Queued,
|
||||
Scheduled,
|
||||
Running,
|
||||
Finished,
|
||||
}
|
||||
|
||||
pub struct CloneableReceiver<T: Clone> {
|
||||
receiver: Receiver<T>,
|
||||
sender: Sender<T>,
|
||||
}
|
||||
|
||||
impl<T: Clone> CloneableReceiver<T> {
|
||||
pub fn new(sender: Sender<T>) -> Self {
|
||||
Self {
|
||||
receiver: sender.subscribe(),
|
||||
sender,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Clone for CloneableReceiver<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
sender: self.sender.clone(),
|
||||
receiver: self.sender.subscribe(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Deref for CloneableReceiver<T> {
|
||||
type Target = Receiver<T>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.receiver
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> DerefMut for CloneableReceiver<T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.receiver
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue