Skip to content

Commit f8b060b

Browse files
committed
refactor: replace sleep-based dispatcher shutdown with notification
- added DISPATCHER_STOPPED notification in dispatcher.rs that fires after all handler tasks complete - refactored idle() in lib.rs to use the notification instead of sleep(Duration::from_secs(2)) — cleaner shutdown coordination
1 parent c056d40 commit f8b060b

3 files changed

Lines changed: 19 additions & 12 deletions

File tree

ferogram/src/dispatcher.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@ use tokio::{
1818

1919
use crate::{Context, Handler, Injector, wait_for_ctrl_c};
2020

21+
/// A notification sent to stop the dispatcher.
2122
pub(super) static STOP_DISPATCHER: LazyLock<Arc<Notify>> =
2223
LazyLock::new(|| Arc::new(Notify::new()));
2324

25+
/// A notification sent when the dispatcher is fully stopped.
26+
pub(super) static DISPATCHER_STOPPED: LazyLock<Arc<Notify>> =
27+
LazyLock::new(|| Arc::new(Notify::new()));
28+
2429
/// A update dispatcher.
2530
///
2631
/// It receives the updates from Telegram by wrapping [`Client`] and
@@ -158,6 +163,8 @@ impl Dispatcher {
158163

159164
tracing::info!("Waiting for any slow handlers to finish...");
160165
while handler_tasks.try_join_next().is_some() {}
166+
167+
DISPATCHER_STOPPED.notify_waiters();
161168
})
162169
}
163170
}

ferogram/src/lib.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@ pub mod filter;
1414
pub mod handler;
1515
mod utils;
1616

17-
use std::{error::Error, time::Duration};
18-
19-
use tokio::time::sleep;
17+
use std::error::Error;
2018

2119
pub use context::Context;
2220
pub use di::{Injector, Resource};
2321
pub use dispatcher::Dispatcher;
24-
use dispatcher::STOP_DISPATCHER;
22+
use dispatcher::{DISPATCHER_STOPPED, STOP_DISPATCHER};
2523
pub use handler::Handler;
2624

2725
pub mod prelude {
@@ -41,15 +39,16 @@ type Result<T> = std::result::Result<T, Box<dyn Error>>;
4139
pub async fn wait_for_ctrl_c() {
4240
tokio::signal::ctrl_c()
4341
.await
44-
.expect("Failed to listen for Ctrl+C signal");
45-
46-
STOP_DISPATCHER.notify_waiters();
47-
48-
// Sleep to let the dispatcher catch all its tasks.
49-
sleep(Duration::from_secs(2)).await;
42+
.expect("Failed to listen for Ctrl+C signal")
5043
}
5144

52-
/// Same as [`wait_for_ctrl_c`].
45+
/// Keep the process alive until a `Ctrl-C` signal is received.
46+
///
47+
/// Unlike [`self::wait_for_ctrl_c`], it waits for all handler tasks spawned by
48+
/// the dispatcher to finish.
5349
pub async fn idle() {
54-
wait_for_ctrl_c().await
50+
wait_for_ctrl_c().await;
51+
52+
STOP_DISPATCHER.notify_waiters();
53+
DISPATCHER_STOPPED.notified().await;
5554
}

flake.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@
3838
}
3939
);
4040
}
41+

0 commit comments

Comments
 (0)