sort_governor/service/
handle.rs1use std::path::PathBuf;
5use std::sync::Arc;
6
7use tokio::sync::{
8 mpsc,
9 oneshot,
10};
11
12use crate::config::SorterConfig;
13use crate::error::SorterError;
14use crate::service::actor::SorterActor;
15use crate::service::command::SorterCommand;
16use crate::service::lease::SortLease;
17use crate::service::pressure::MemoryPressure;
18use crate::service::stats::SorterStats;
19use crate::spec::SortSpec;
20
21const COMMAND_CHANNEL_CAPACITY: usize = 256;
23
24#[derive(Clone)]
27pub struct SorterHandle {
28 tx: mpsc::Sender<SorterCommand>,
29}
30
31impl SorterHandle {
32 #[must_use]
37 pub fn spawn(
38 config: SorterConfig,
39 fd_budget: u32,
40 pressure: Arc<dyn MemoryPressure>,
41 scratch_root: PathBuf,
42 ) -> Self {
43 let (tx, rx) = mpsc::channel(COMMAND_CHANNEL_CAPACITY);
44 let actor = SorterActor::new(config, fd_budget, pressure, scratch_root);
45 tokio::spawn(actor.run(rx));
46 Self { tx }
47 }
48
49 pub async fn submit(&self, spec: SortSpec) -> Result<SortLease, SorterError> {
57 let (reply, rx) = oneshot::channel();
58 self.tx
59 .send(SorterCommand::Submit { spec, reply })
60 .await
61 .map_err(|_| SorterError::Gone)?;
62 rx.await.map_err(|_| SorterError::Gone)?
63 }
64
65 pub async fn stats(&self) -> Result<SorterStats, SorterError> {
71 let (reply, rx) = oneshot::channel();
72 self.tx
73 .send(SorterCommand::Stats { reply })
74 .await
75 .map_err(|_| SorterError::Gone)?;
76 rx.await.map_err(|_| SorterError::Gone)
77 }
78}