Skip to content

Commit d5e8a9d

Browse files
bkioshnaido-mth
authored andcommitted
wip: implement quiet timer
Signed-off-by: bkioshn <[email protected]>
1 parent 473f9a4 commit d5e8a9d

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

hermes/bin/src/runtime_extensions/hermes/doc_sync/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use once_cell::sync::Lazy;
55

66
mod event;
77
mod host;
8+
mod timers;
89

910
/// Initialize state. Which is mapping from String hash to String itself.
1011
///
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mod quiet;
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//! Quiet timer management for Document Sync protocol.
2+
//!
3+
//! Specification and terminology is defined:
4+
//! <https://github.com/input-output-hk/hermes/blob/main/docs/src/architecture/08_concepts/document_sync/protocol_spec.md#timers-and-retries>
5+
6+
use std::{sync::Arc, time::Duration};
7+
8+
use tokio::{
9+
sync::{Mutex, Notify},
10+
task::JoinHandle,
11+
time::Instant,
12+
};
13+
14+
use crate::{app::ApplicationName, ipfs::hermes_ipfs_publish};
15+
16+
/// Minimum quiet period in seconds
17+
const T_QUIET_MIN: u64 = 20;
18+
/// Maximum quiet period in seconds
19+
const T_QUIET_MAX: u64 = 60;
20+
21+
/// Configuration for quiet timers per topic channel.
22+
#[derive(Debug, Clone)]
23+
pub struct QuietTimersConfig {
24+
// Quiet period re-announcement for .new
25+
pub t_quiet_min: Duration,
26+
pub t_quiet_max: Duration,
27+
}
28+
29+
impl Default for QuietTimersConfig {
30+
fn default() -> Self {
31+
Self {
32+
t_quiet_min: Duration::from_secs(T_QUIET_MIN),
33+
t_quiet_max: Duration::from_secs(T_QUIET_MAX),
34+
}
35+
}
36+
}
37+
38+
impl QuietTimersConfig {
39+
/// Tquiet uniformly random within [T_QUIET_MIN, T_QUIET_MAX]
40+
fn random_quiet(&self) -> Duration {
41+
let t_quiet = rand::random_range(self.t_quiet_min..=self.t_quiet_max);
42+
Duration::from_secs(t_quiet.as_secs())
43+
}
44+
}
45+
46+
/// Timer state per channel
47+
pub struct QuietTimersState {
48+
/// Timer configuration
49+
pub cfg: QuietTimersConfig,
50+
/// Last `.new` topic received
51+
pub last_new_received: Mutex<Instant>,
52+
/// Handle for the background keepalive task.
53+
pub keepalive_task: Mutex<Option<JoinHandle<()>>>,
54+
/// Notification for resetting the timer
55+
pub reset_new_notify: Notify,
56+
/// Application name
57+
pub app_name: ApplicationName,
58+
/// Channel topic
59+
pub channel_topic: String,
60+
}
61+
62+
impl QuietTimersState {
63+
pub fn new(
64+
cfg: QuietTimersConfig,
65+
app_name: ApplicationName,
66+
channel_topic: &str,
67+
) -> Arc<Self> {
68+
Arc::new(Self {
69+
cfg,
70+
last_new_received: Mutex::new(Instant::now()),
71+
keepalive_task: Mutex::new(None),
72+
reset_new_notify: Notify::new(),
73+
app_name,
74+
channel_topic: channel_topic.to_string(),
75+
})
76+
}
77+
78+
/// Start the quiet period keepalive timer for .new topic
79+
pub fn start_quiet_timer(&self) -> anyhow::Result<()> {
80+
todo!()
81+
}
82+
83+
async fn run_quiet_timer(self) -> anyhow::Result<()> {
84+
loop {
85+
let sleep_dur = self.cfg.random_quiet();
86+
87+
tokio::select! {
88+
// When timer expire, send keepalive
89+
_ = tokio::time::sleep(sleep_dur) => {
90+
if let Err(err) = self.send_new_keepalive() {
91+
tracing::warn!("Failed to send .new keepalive: {:?}", err);
92+
}
93+
}
94+
// Notify that a new topic is received
95+
_ = self.reset_new_notify.notified() => {
96+
continue
97+
}
98+
}
99+
}
100+
}
101+
102+
fn send_new_keepalive(&self) -> anyhow::Result<()> {
103+
// TODO - implement a proper keepalive payload
104+
let payload = vec![];
105+
hermes_ipfs_publish(&self.app_name, &self.channel_topic, payload)
106+
.map_err(anyhow::Error::msg)?;
107+
Ok(())
108+
}
109+
110+
/// Reset quiet-period timer (call on every received or posted .new)
111+
pub async fn reset_quiet_timer(&self) {
112+
todo!()
113+
}
114+
}

0 commit comments

Comments
 (0)