Skip to main content

runtime/
notifier.rs

1use crossbeam_channel::Sender;
2
3use crate::{status::Status, RuntimeError};
4
5/// A thread status notifier, that allows a thread to notify the `Runtime` of the current status of the thread.
6#[derive(Debug)]
7pub struct Notifier {
8	thread_name: String,
9	sender: Sender<(String, Status)>,
10}
11
12impl Notifier {
13	pub(crate) fn new(thread_name: &str, sender: Sender<(String, Status)>) -> Self {
14		Self {
15			thread_name: String::from(thread_name),
16			sender,
17		}
18	}
19
20	/// Notify the `Runtime` that the thread is busy processing.
21	#[inline]
22	#[allow(clippy::missing_panics_doc)]
23	pub fn busy(&self) {
24		self.sender
25			.send((String::from(&self.thread_name), Status::Busy))
26			.unwrap();
27	}
28
29	/// Notify the `Runtime` to request that the `Runtime` and all other registered thread pause processing.
30	#[inline]
31	#[allow(clippy::missing_panics_doc)]
32	pub fn request_pause(&self) {
33		self.sender
34			.send((String::from(&self.thread_name), Status::RequestPause))
35			.unwrap();
36	}
37
38	/// Notify the `Runtime` to request that the `Runtime` and all other registered thread resume processing.
39	#[inline]
40	#[allow(clippy::missing_panics_doc)]
41	pub fn request_resume(&self) {
42		self.sender
43			.send((String::from(&self.thread_name), Status::RequestResume))
44			.unwrap();
45	}
46
47	/// Notify the `Runtime` to request that the `Runtime` and all other registered thread end processing.
48	#[inline]
49	#[allow(clippy::missing_panics_doc)]
50	pub fn request_end(&self) {
51		self.sender
52			.send((String::from(&self.thread_name), Status::RequestEnd))
53			.unwrap();
54	}
55
56	/// Notify the `Runtime` that the thread is waiting for new data or messages to process.
57	#[inline]
58	#[allow(clippy::missing_panics_doc)]
59	pub fn wait(&self) {
60		self.sender
61			.send((String::from(&self.thread_name), Status::Waiting))
62			.unwrap();
63	}
64
65	/// Notify the `Runtime` that the thread is in a permanent error state.
66	#[inline]
67	#[allow(clippy::missing_panics_doc)]
68	pub fn error(&self, err: RuntimeError) {
69		self.sender
70			.send((String::from(&self.thread_name), Status::Error(err)))
71			.unwrap();
72	}
73
74	/// Notify the `Runtime` that the thread has ended processing.
75	#[inline]
76	#[allow(clippy::missing_panics_doc)]
77	pub fn end(&self) {
78		self.sender
79			.send((String::from(&self.thread_name), Status::Ended))
80			.unwrap();
81	}
82}
83
84#[cfg(test)]
85mod tests {
86	use claim::assert_ok_eq;
87	use crossbeam_channel::unbounded;
88
89	use super::*;
90
91	#[test]
92	fn busy() {
93		let (sender, receiver) = unbounded();
94		let notifier = Notifier::new("name", sender);
95		notifier.busy();
96		assert_ok_eq!(receiver.recv(), (String::from("name"), Status::Busy));
97	}
98
99	#[test]
100	fn request_pause() {
101		let (sender, receiver) = unbounded();
102		let notifier = Notifier::new("name", sender);
103		notifier.request_pause();
104		assert_ok_eq!(receiver.recv(), (String::from("name"), Status::RequestPause));
105	}
106
107	#[test]
108	fn request_resume() {
109		let (sender, receiver) = unbounded();
110		let notifier = Notifier::new("name", sender);
111		notifier.request_resume();
112		assert_ok_eq!(receiver.recv(), (String::from("name"), Status::RequestResume));
113	}
114
115	#[test]
116	fn request_end() {
117		let (sender, receiver) = unbounded();
118		let notifier = Notifier::new("name", sender);
119		notifier.request_end();
120		assert_ok_eq!(receiver.recv(), (String::from("name"), Status::RequestEnd));
121	}
122
123	#[test]
124	fn error() {
125		let (sender, receiver) = unbounded();
126		let notifier = Notifier::new("name", sender);
127		notifier.error(RuntimeError::ThreadError(String::from("error")));
128		assert_ok_eq!(
129			receiver.recv(),
130			(
131				String::from("name"),
132				Status::Error(RuntimeError::ThreadError(String::from("error")))
133			)
134		);
135	}
136
137	#[test]
138	fn end() {
139		let (sender, receiver) = unbounded();
140		let notifier = Notifier::new("name", sender);
141		notifier.end();
142		assert_ok_eq!(receiver.recv(), (String::from("name"), Status::Ended));
143	}
144}