1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Copyright (c) Sean Lawlor
//
// This source code is licensed under both the MIT license found in the
// LICENSE-MIT file in the root directory of this source tree.
//! Actor watchdogs
//!
//! An actor can use a watchdog to terminate itself if it's not feeding the watchdog. After an actor
//! is registered with the watchdog, it has to ping the watchdog within the set timeout.
//!
//! This can be used by actors that has certain deadlines, for example user interactivity.
//!
//! If an application has a per-user actor and is waiting for a user response within a certain time,
//! it can use this module to do so. The actor can either be stopped or killed.
//!
//! To use the watchdog, the application has to first call [register] and then call [ping] on a
//! regular interval. The watchdog can be disabled by calling [unregister], but its usage is
//! optional. If an actor terminates for any reason before the watchdog fires, it is simply cleaned
//! up.
//!
//! ```rust
//! use ractor::*;
//! use ractor::concurrency::Duration;
//! use ractor_actors::watchdog;
//! use ractor_actors::watchdog::TimeoutStrategy;
//! struct MyActor;
//!
//! enum MyActorMsg {
//! UserInput(String),
//! }
//!
//! #[cfg_attr(feature = "async-trait", async_trait::async_trait)]
//! impl Actor for MyActor {
//! type Msg = MyActorMsg;
//! type State = ();
//! type Arguments = ();
//!
//! async fn pre_start(
//! &self,
//! myself: ActorRef<Self::Msg>,
//! args: Self::Arguments,
//! ) -> Result<Self::State, ActorProcessingErr> {
//! // Register with the watchdog. If this actor don't ping it once every second, it will
//! // be stopped.
//! watchdog::register(
//! myself.get_cell(),
//! Duration::from_secs(1),
//! TimeoutStrategy::Stop,
//! )
//! .await?;
//!
//! Ok(())
//! }
//!
//! async fn post_stop(
//! &self,
//! _: ActorRef<Self::Msg>,
//! _: &mut Self::State,
//! ) -> Result<(), ActorProcessingErr> {
//! println!("Input timeout!");
//!
//! Ok(())
//! }
//! async fn handle(
//! &self,
//! myself: ActorRef<Self::Msg>,
//! message: Self::Msg,
//! state: &mut Self::State,
//! ) -> Result<(), ActorProcessingErr> {
//! match message {
//! Self::Msg::UserInput(msg) => {
//! // When we get a message from the user, ping the watchdog
//! watchdog::ping(myself.get_id()).await?;
//! println!("User input: {}", msg);
//! }
//! // ... handle other messages
//! }
//!
//! Ok(())
//! }
//! }
//! ```
//!
//! # Implementation note
//!
//! The watchdog is implemented as a single actor internally. This means that it uses the same,
//! global executors as the actors it is monitoring. If some actors are doing CPU bound work the
//! internal actor might be starved for CPU and not able to kill the monitored actors.
//!
//! Make sure that this fits your use-case.
use r#;
use ;
use OnceCell;
/// See [register]. Controls what the watchdog will do on timeout.
/// The stop reason that will be used when an actor is stopped by a watchdog timeout.
pub const WATCHDOG_TIMEOUT: &str = "watchdog_timeout";
/// Register an actor with the watchdog.
///
/// # Arguments
///
/// * `actor` - the actor that is to be watched.
/// * `duration` - the max duration between each ping.
/// * `timeout_strategy` - What the actor should do on a timeout. See [TimeoutStrategy].
///
pub async
/// Unregister an actor from the watchdog.
///
/// # Arguments
///
/// * `actor` - the actor to unregister.
pub async
/// Send a ping to the watchdog. Doing this within the timeout prevents the watchdog from
/// terminating the actor.
///
/// # Arguments
///
/// * `actor` - the actor that is sending the ping.
pub async
/// The return value from [stats] that describes
pub async
static WATCHDOG: =
const_new;
async
async
async