use std::sync::Arc;
use std::time::Duration;
use tokio::sync::mpsc::{Receiver, Sender};
use tokio::sync::{mpsc, oneshot};
use tokio::task::JoinHandle;
use tokio::time::sleep;
use tracing::warn;
use crate::api::SearchResult;
use crate::{DehashedApi, DehashedError, Query};
#[derive(Debug)]
pub struct ScheduledRequest {
query: Query,
ret: oneshot::Sender<Result<SearchResult, DehashedError>>,
}
impl ScheduledRequest {
pub fn new(query: Query, ret: oneshot::Sender<Result<SearchResult, DehashedError>>) -> Self {
Self { query, ret }
}
}
#[derive(Clone)]
pub struct Scheduler {
handle: Arc<JoinHandle<()>>,
tx: Sender<ScheduledRequest>,
}
impl Scheduler {
pub(crate) fn new(api: &DehashedApi) -> Self {
let (tx, rx) = mpsc::channel(5);
let mut rx: Receiver<ScheduledRequest> = rx;
let task_api = api.clone();
let handle = tokio::spawn(async move {
while let Some(req) = rx.recv().await {
let res = task_api.search(req.query).await;
if req.ret.send(res).is_err() {
warn!("Couldn't send result back through channel");
}
sleep(Duration::from_millis(200)).await;
}
});
Self {
tx,
handle: Arc::new(handle),
}
}
pub fn retrieve_sender(&self) -> Sender<ScheduledRequest> {
self.tx.clone()
}
pub fn stop_scheduler(self) {
self.handle.abort();
}
}