@@ -2,13 +2,17 @@ use anyhow::anyhow;
2
2
use mithril_common:: StdResult ;
3
3
use slog_scope:: debug;
4
4
use std:: { fmt:: Debug , sync:: Arc , time:: Duration } ;
5
- use tokio:: sync:: { mpsc:: UnboundedSender , Mutex } ;
5
+ use tokio:: {
6
+ sync:: { mpsc:: UnboundedSender , Mutex } ,
7
+ time:: Instant ,
8
+ } ;
6
9
7
10
/// A message repeater will send a message to a channel at a given delay
8
11
pub struct MessageRepeater < M : Clone + Debug + Sync + Send + ' static > {
9
12
message : Arc < Mutex < Option < M > > > ,
10
13
tx_message : UnboundedSender < M > ,
11
14
delay : Duration ,
15
+ next_repeat_at : Arc < Mutex < Option < Instant > > > ,
12
16
}
13
17
14
18
impl < M : Clone + Debug + Sync + Send + ' static > MessageRepeater < M > {
@@ -18,18 +22,31 @@ impl<M: Clone + Debug + Sync + Send + 'static> MessageRepeater<M> {
18
22
message : Arc :: new ( Mutex :: new ( None ) ) ,
19
23
tx_message,
20
24
delay,
25
+ next_repeat_at : Arc :: new ( Mutex :: new ( None ) ) ,
21
26
}
22
27
}
23
28
29
+ async fn reset_next_repeat_at ( & self ) {
30
+ debug ! ( "MessageRepeater: reset next_repeat_at" ) ;
31
+ * self . next_repeat_at . lock ( ) . await = Some ( Instant :: now ( ) + self . delay ) ;
32
+ }
33
+
24
34
/// Set the message to repeat
25
35
pub async fn set_message ( & self , message : M ) {
26
36
debug ! ( "MessageRepeater: set message" ; "message" => format!( "{:#?}" , message) ) ;
27
37
* self . message . lock ( ) . await = Some ( message) ;
38
+ self . reset_next_repeat_at ( ) . await ;
28
39
}
29
40
30
41
/// Start repeating the message if any
31
42
pub async fn repeat_message ( & self ) -> StdResult < ( ) > {
32
- tokio:: time:: sleep ( self . delay ) . await ;
43
+ let wait_delay = match self . next_repeat_at . lock ( ) . await . as_ref ( ) {
44
+ None => self . delay ,
45
+ Some ( next_repeat_at) => next_repeat_at
46
+ . checked_duration_since ( Instant :: now ( ) )
47
+ . unwrap_or_default ( ) ,
48
+ } ;
49
+ tokio:: time:: sleep ( wait_delay) . await ;
33
50
match self . message . lock ( ) . await . as_ref ( ) {
34
51
Some ( message) => {
35
52
debug ! ( "MessageRepeater: repeat message" ; "message" => format!( "{:#?}" , message) ) ;
@@ -41,6 +58,7 @@ impl<M: Clone + Debug + Sync + Send + 'static> MessageRepeater<M> {
41
58
debug ! ( "MessageRepeater: no message to repeat" ) ;
42
59
}
43
60
}
61
+ self . reset_next_repeat_at ( ) . await ;
44
62
45
63
Ok ( ( ) )
46
64
}
0 commit comments