use anyhow::Result;
use uuid::Uuid;
use crate::crypto::PublicKey;
use crate::linked_data::Link;
#[derive(Debug, Clone)]
pub enum Job {
SyncBucket {
bucket_id: Uuid,
target_link: Link,
target_height: u64,
peer_id: PublicKey,
},
DownloadPins {
pins_link: Link,
peer_ids: Vec<PublicKey>,
},
PingPeer {
bucket_id: Uuid,
peer_id: PublicKey,
},
}
#[derive(Debug, Clone)]
pub struct JobDispatcher {
tx: flume::Sender<Job>,
}
impl JobDispatcher {
pub fn new() -> (Self, JobReceiver) {
let (tx, rx) = flume::unbounded();
(Self { tx }, JobReceiver { rx })
}
pub fn dispatch(&self, job: Job) -> Result<()> {
tracing::info!("JOB_DISPATCHER: Dispatching job: {:?}", job);
self.tx
.send(job)
.map_err(|_| anyhow::anyhow!("job receiver has been dropped"))
}
pub fn dispatch_download_pins(&self, pins_link: Link, peer_ids: Vec<PublicKey>) -> Result<()> {
self.dispatch(Job::DownloadPins {
pins_link,
peer_ids,
})
}
pub fn dispatch_sync(
&self,
bucket_id: Uuid,
target_link: Link,
target_height: u64,
peer_id: PublicKey,
) -> Result<()> {
self.dispatch(Job::SyncBucket {
bucket_id,
target_link,
target_height,
peer_id,
})
}
}
#[derive(Debug)]
pub struct JobReceiver {
rx: flume::Receiver<Job>,
}
impl JobReceiver {
pub fn recv(&self) -> Option<Job> {
self.rx.recv().ok()
}
pub fn try_recv(&self) -> Option<Job> {
self.rx.try_recv().ok()
}
pub fn into_async(self) -> flume::r#async::RecvStream<'static, Job> {
self.rx.into_stream()
}
}