use crate::{ action::{Action, MsgAction, Records}, message::wrapper::Message, name::{Name, NameType, Names}, queue::{ data_director::{Include, Path, RegMsg, Register}, router::Queue, }, }; use std::{ sync::mpsc::channel, thread::{sleep, spawn}, time::Duration, }; pub struct Clock { queue: Queue, } impl Clock { fn new(queue: Queue) -> Self { Self { queue: queue } } pub fn doc_names() -> Vec { vec![Name::english("clock")] } /* fn get_name() -> Name { Name::english("clock") } */ fn gen_message() -> Message { Message::new( Clock::doc_names()[0].clone(), MsgAction::OnUpdate(Records::new(Clock::doc_names(), Names::new())), ) } pub fn get_path() -> Path { Path::new( Include::All, Include::Just(Clock::doc_names()[0].clone().into()), Include::Just(Action::OnUpdate), ) } pub fn start(mut queue: Queue) { let clock = Clock::new(queue.clone()); let (tx, rx) = channel(); let id = queue.add_sender(tx); let reg_msg = Register::new(id, RegMsg::AddDocName(Clock::doc_names())); let msg = Message::new(NameType::None, reg_msg.clone()); queue.send(msg); rx.recv().unwrap(); spawn(move || { clock.listen(); }); } fn listen(&self) { loop { self.queue.send(Clock::gen_message()); sleep(Duration::from_secs(1)); } } } #[cfg(test)] pub mod clock_test_support { use super::*; pub fn gen_clock_message() -> Message { Clock::gen_message() } } #[cfg(test)] mod clocks { use super::*; use crate::queue::data_director::{Include, Path}; use chrono::{TimeDelta, Utc}; static TIMEOUT: Duration = Duration::from_millis(1500); #[test] fn does_clock_send_reply_every_second() { let mut queue = Queue::new(); let (tx, rx) = channel(); let id = queue.add_sender(tx); let request = Register::new( id.clone(), RegMsg::AddRoute(Path::new(Include::All, Include::All, Include::All)), ); queue.send(Message::new(NameType::None, request)); rx.recv_timeout(TIMEOUT).unwrap(); let mut holder: Vec = Vec::new(); let start = Utc::now(); Clock::start(queue.clone()); while holder.len() < 2 { holder.push(rx.recv_timeout(TIMEOUT).unwrap()); } let end = Utc::now(); assert!((end - start) > TimeDelta::seconds(1)); assert!((end - start) < TimeDelta::seconds(2)); let reg_request = Register::new(id, RegMsg::GetNameID(Clock::doc_names()[0].clone())); queue.send(Message::new(NameType::None, reg_request)); rx.recv_timeout(TIMEOUT).unwrap(); for msg in holder.iter() { let action = msg.get_action(); match action { MsgAction::OnUpdate(result) => assert_eq!(result.len(), 0), _ => unreachable!("got {:?}, should have been empty record", action), } } } }