nautilus_common/
runner.rs1use std::{
17 cell::{OnceCell, RefCell},
18 collections::VecDeque,
19 rc::Rc,
20};
21
22use crate::{
23 clock::Clock,
24 messages::data::{DataEvent, DataResponse, SubscriptionCommand},
25 timer::TimeEvent,
26};
27
28pub trait DataQueue {
29 fn push(&mut self, event: DataEvent);
30}
31
32pub type GlobalDataQueue = Rc<RefCell<dyn DataQueue>>;
33
34pub struct SyncDataQueue(VecDeque<DataEvent>);
35
36impl DataQueue for SyncDataQueue {
37 fn push(&mut self, event: DataEvent) {
38 self.0.push_back(event);
39 }
40}
41
42#[must_use]
43pub fn get_data_queue() -> Rc<RefCell<dyn DataQueue>> {
44 DATA_QUEUE
45 .try_with(|dq| {
46 dq.get()
47 .expect("Data queue should be initialized by runner")
48 .clone()
49 })
50 .expect("Should be able to access thread local storage")
51}
52
53pub fn set_data_queue(dq: Rc<RefCell<dyn DataQueue>>) {
54 DATA_QUEUE
55 .try_with(|deque| {
56 assert!(deque.set(dq).is_ok(), "Global data queue already set");
57 })
58 .expect("Should be able to access thread local storage");
59}
60
61pub type GlobalClock = Rc<RefCell<dyn Clock>>;
62
63#[must_use]
64pub fn get_clock() -> Rc<RefCell<dyn Clock>> {
65 CLOCK
66 .try_with(|clock| {
67 clock
68 .get()
69 .expect("Clock should be initialized by runner")
70 .clone()
71 })
72 .expect("Should be able to access thread local storage")
73}
74
75pub fn set_clock(c: Rc<RefCell<dyn Clock>>) {
76 CLOCK
77 .try_with(|clock| {
78 assert!(clock.set(c).is_ok(), "Global clock already set");
79 })
80 .expect("Should be able to access thread local clock");
81}
82
83pub type MessageBusCommands = Rc<RefCell<VecDeque<SubscriptionCommand>>>;
84
85#[must_use]
87pub fn get_msgbus_cmd() -> MessageBusCommands {
88 MSGBUS_CMD
89 .try_with(std::clone::Clone::clone)
90 .expect("Should be able to access thread local storage")
91}
92
93thread_local! {
94 static CLOCK: OnceCell<GlobalClock> = OnceCell::new();
95 static DATA_QUEUE: OnceCell<GlobalDataQueue> = OnceCell::new();
96 static MSGBUS_CMD: MessageBusCommands = Rc::new(RefCell::new(VecDeque::new()));
97}
98
99pub trait SendResponse {
100 fn send(&self, resp: DataResponse);
101}
102
103pub type DataResponseQueue = Rc<RefCell<SyncDataQueue>>;
104
105#[allow(clippy::large_enum_variant)]
107pub enum RunnerEvent {
108 Data(DataEvent),
109 Timer(TimeEvent),
110}