use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::{
mpsc,
oneshot,
};
use crate::config::SorterConfig;
use crate::error::SorterError;
use crate::service::actor::SorterActor;
use crate::service::command::SorterCommand;
use crate::service::lease::SortLease;
use crate::service::pressure::MemoryPressure;
use crate::service::stats::SorterStats;
use crate::spec::SortSpec;
const COMMAND_CHANNEL_CAPACITY: usize = 256;
#[derive(Clone)]
pub struct SorterHandle {
tx: mpsc::Sender<SorterCommand>,
}
impl SorterHandle {
#[must_use]
pub fn spawn(
config: SorterConfig,
fd_budget: u32,
pressure: Arc<dyn MemoryPressure>,
scratch_root: PathBuf,
) -> Self {
let (tx, rx) = mpsc::channel(COMMAND_CHANNEL_CAPACITY);
let actor = SorterActor::new(config, fd_budget, pressure, scratch_root);
tokio::spawn(actor.run(rx));
Self { tx }
}
pub async fn submit(&self, spec: SortSpec) -> Result<SortLease, SorterError> {
let (reply, rx) = oneshot::channel();
self.tx
.send(SorterCommand::Submit { spec, reply })
.await
.map_err(|_| SorterError::Gone)?;
rx.await.map_err(|_| SorterError::Gone)?
}
pub async fn stats(&self) -> Result<SorterStats, SorterError> {
let (reply, rx) = oneshot::channel();
self.tx
.send(SorterCommand::Stats { reply })
.await
.map_err(|_| SorterError::Gone)?;
rx.await.map_err(|_| SorterError::Gone)
}
}