manycastr/orchestrator/
cli.rs1use crate::custom_module::manycastr::WorkerStatus::Disconnected;
2use crate::custom_module::manycastr::{End, Instruction, instruction};
3use crate::orchestrator::{MeasurementHandle, WorkerRegistry};
4use futures_core::Stream;
5use log::warn;
6use std::pin::Pin;
7use std::task::{Context, Poll};
8use tokio::sync::mpsc;
9
10pub struct CLIReceiver<T> {
15 pub(crate) inner: mpsc::Receiver<T>,
17 pub(crate) measurement: MeasurementHandle,
19 pub(crate) workers: WorkerRegistry,
21 pub(crate) m_id: u32,
23}
24
25impl<T> Stream for CLIReceiver<T> {
26 type Item = T;
27
28 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<T>> {
29 self.inner.poll_recv(cx)
30 }
31}
32
33impl<T> Drop for CLIReceiver<T> {
34 fn drop(&mut self) {
35 let participant_ids: Vec<u32> = {
37 let mut lock = self.measurement.write().unwrap();
38 match lock.as_ref() {
39 Some(state) if state.m_id == self.m_id => {
40 warn!(
41 "[Orchestrator] CLI dropped during an active measurement, terminating measurement"
42 );
43 let ids = state.participants.keys().copied().collect();
44 *lock = None; ids
46 }
47 _ => return,
49 }
50 };
51
52 let abort = Instruction {
54 instruction_type: Some(instruction::InstructionType::End(End { code: 1 })),
55 };
56 let senders: Vec<_> = self.workers.lock().unwrap().clone();
57 for sender in senders {
58 if !participant_ids.contains(&sender.worker_id) || sender.get_status() == Disconnected {
59 continue;
60 }
61 if sender.try_send(Ok(abort.clone())).is_err() {
62 warn!(
63 "[Orchestrator] Could not send abort instruction to worker {}",
64 sender.hostname
65 );
66 }
67 sender.finished();
68 }
69 }
70}