flarrow_builtins/
timer.rs1use std::time::Duration;
2
3use crate::prelude::*;
4
5static TOKIO_RUNTIME: std::sync::LazyLock<tokio::runtime::Runtime> =
6 std::sync::LazyLock::new(|| {
7 tokio::runtime::Runtime::new().expect("Failed to create Tokio runtime")
8 });
9
10fn default_runtime<T: Send + 'static>(
11 task: impl Future<Output = T> + Send + 'static,
12) -> tokio::task::JoinHandle<T> {
13 match tokio::runtime::Handle::try_current() {
14 Ok(handle) => handle.spawn(task),
15 Err(_) => TOKIO_RUNTIME.spawn(task),
16 }
17}
18
19pub struct Timer {
20 pub output: Output<String>,
21 pub frequency: f64,
22}
23
24#[node(runtime = "default_runtime")]
25impl Node for Timer {
26 async fn new(
27 _: Inputs,
28 mut outputs: Outputs,
29 configuration: serde_yml::Value,
30 ) -> eyre::Result<Box<dyn Node>>
31 where
32 Self: Sized,
33 {
34 let frequency = match configuration.get("frequency") {
35 Some(serde_yml::Value::Number(number)) => number.as_f64().unwrap_or(1.0),
36 _ => 1.0,
37 };
38
39 Ok(Box::new(Self {
40 output: outputs.with("out").await?,
41 frequency,
42 }) as Box<dyn Node>)
43 }
44
45 async fn start(self: Box<Self>) -> eyre::Result<()> {
46 loop {
47 tokio::time::sleep(Duration::from_millis((1000.0 / self.frequency) as u64)).await;
48
49 self.output
50 .send("tick".to_string())
51 .wrap_err("Failed to send message")?;
52 }
53 }
54}