summaryrefslogtreecommitdiffstats
path: root/crates/core/tedge_lib/src/mainloop/ticking.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/core/tedge_lib/src/mainloop/ticking.rs')
-rw-r--r--crates/core/tedge_lib/src/mainloop/ticking.rs74
1 files changed, 74 insertions, 0 deletions
diff --git a/crates/core/tedge_lib/src/mainloop/ticking.rs b/crates/core/tedge_lib/src/mainloop/ticking.rs
new file mode 100644
index 00000000..887ccc5b
--- /dev/null
+++ b/crates/core/tedge_lib/src/mainloop/ticking.rs
@@ -0,0 +1,74 @@
+//! Utility functionality for building a mainloop for a plugin
+//!
+
+use std::sync::Arc;
+
+use tedge_api::error::PluginError;
+use tedge_api::CancellationToken;
+use tracing::debug;
+use tracing::error;
+use tracing::trace;
+
+pub struct MainloopTick<State: Sized> {
+ pub(crate) state: State,
+ pub(crate) logging: bool,
+ pub(crate) stopper: CancellationToken,
+ pub(crate) duration: std::time::Duration,
+}
+
+impl<State> MainloopTick<State>
+where
+ State: Sized,
+{
+ #[must_use]
+ pub fn with_logging(mut self, logging: bool) -> Self {
+ self.logging = logging;
+ self
+ }
+
+ #[tracing::instrument(skip_all)]
+ pub async fn run<Func, Fut>(self, func: Func) -> Result<(), PluginError>
+ where
+ Func: Fn(Arc<State>) -> Fut,
+ Fut: futures::future::Future<Output = Result<(), PluginError>>,
+ {
+ debug!(
+ "Building ticking mainloop with interval = {:?}",
+ self.duration
+ );
+ let mut interval = tokio::time::interval(self.duration);
+ let state = Arc::new(self.state);
+ loop {
+ tokio::select! {
+ _tick = interval.tick() => {
+ if self.logging {
+ trace!("Tick");
+ }
+
+ match func(state.clone()).await {
+ Ok(_) if self.logging => log::debug!("Ok(_) from mainloop function"),
+ Err(e) if self.logging => {
+ error!("Error from mainloop function: {:?}", e);
+ return Err(e)
+ },
+ _ => {},
+ }
+
+ if self.logging {
+ trace!("func returned");
+ }
+ },
+
+ _ = self.stopper.cancelled() => {
+ if self.logging {
+ trace!("stopping...");
+ }
+
+ break;
+ }
+ }
+ }
+
+ Ok(())
+ }
+}