@@ -44,6 +44,7 @@ use crate::mailbox::PyMailbox;
44
44
use crate :: runtime:: signal_safe_block_on;
45
45
use crate :: shape:: PyShape ;
46
46
use crate :: supervision:: SupervisionError ;
47
+ use crate :: supervision:: Unhealthy ;
47
48
48
49
// A wrapper around `ProcMesh` which keeps track of all `RootActorMesh`s that it spawns.
49
50
pub struct TrackedProcMesh {
@@ -117,7 +118,7 @@ pub struct PyProcMesh {
117
118
proc_events : SharedCell < Mutex < ProcEvents > > ,
118
119
user_monitor_receiver : SharedCell < Mutex < mpsc:: UnboundedReceiver < ProcEvent > > > ,
119
120
user_monitor_registered : Arc < AtomicBool > ,
120
- unhealthy_event : Arc < Mutex < Option < Option < ProcEvent > > > > ,
121
+ unhealthy_event : Arc < Mutex < Unhealthy < ProcEvent > > > ,
121
122
}
122
123
123
124
fn allocate_proc_mesh < ' py > ( py : Python < ' py > , alloc : & PyAlloc ) -> PyResult < Bound < ' py , PyAny > > {
@@ -162,15 +163,15 @@ impl PyProcMesh {
162
163
let proc_events = SharedCell :: from ( Mutex :: new ( proc_mesh. events ( ) . unwrap ( ) ) ) ;
163
164
let ( user_sender, user_receiver) = mpsc:: unbounded_channel :: < ProcEvent > ( ) ;
164
165
let user_monitor_registered = Arc :: new ( AtomicBool :: new ( false ) ) ;
165
- let unhealthy_event = Arc :: new ( Mutex :: new ( None ) ) ;
166
+ let unhealthy_event = Arc :: new ( Mutex :: new ( Unhealthy :: SoFarSoGood ) ) ;
166
167
let monitor = tokio:: spawn ( Self :: default_proc_mesh_monitor (
167
168
proc_events
168
169
. borrow ( )
169
170
. expect ( "borrowing immediately after creation" ) ,
170
171
world_id,
171
172
user_sender,
172
- user_monitor_registered . clone ( ) ,
173
- unhealthy_event . clone ( ) ,
173
+ Arc :: clone ( & user_monitor_registered ) ,
174
+ Arc :: clone ( & unhealthy_event ) ,
174
175
) ) ;
175
176
Self {
176
177
inner : SharedCell :: from ( TrackedProcMesh :: from ( proc_mesh) ) ,
@@ -188,7 +189,7 @@ impl PyProcMesh {
188
189
world_id : WorldId ,
189
190
user_sender : mpsc:: UnboundedSender < ProcEvent > ,
190
191
user_monitor_registered : Arc < AtomicBool > ,
191
- unhealthy_event : Arc < Mutex < Option < Option < ProcEvent > > > > ,
192
+ unhealthy_event : Arc < Mutex < Unhealthy < ProcEvent > > > ,
192
193
) {
193
194
loop {
194
195
let mut proc_events = events. lock ( ) . await ;
@@ -197,15 +198,15 @@ impl PyProcMesh {
197
198
let mut inner_unhealthy_event = unhealthy_event. lock( ) . await ;
198
199
match event {
199
200
None => {
200
- * inner_unhealthy_event = Some ( None ) ;
201
+ * inner_unhealthy_event = Unhealthy :: StreamClosed ;
201
202
tracing:: info!( "ProcMesh {}: alloc has stopped" , world_id) ;
202
203
break ;
203
204
}
204
205
Some ( event) => match event {
205
206
// Graceful stops can be ignored.
206
207
ProcEvent :: Stopped ( _, ProcStopReason :: Stopped ) => continue ,
207
208
event => {
208
- * inner_unhealthy_event = Some ( Some ( event. clone( ) ) ) ;
209
+ * inner_unhealthy_event = Unhealthy :: Crashed ( event. clone( ) ) ;
209
210
tracing:: info!( "ProcMesh {}: {}" , world_id, event) ;
210
211
if user_monitor_registered. load( std:: sync:: atomic:: Ordering :: SeqCst ) {
211
212
if user_sender. send( event) . is_err( ) {
@@ -218,7 +219,7 @@ impl PyProcMesh {
218
219
}
219
220
_ = events. preempted( ) => {
220
221
let mut inner_unhealthy_event = unhealthy_event. lock( ) . await ;
221
- * inner_unhealthy_event = Some ( None ) ;
222
+ * inner_unhealthy_event = Unhealthy :: StreamClosed ;
222
223
tracing:: info!( "ProcMesh {}: is stopped" , world_id) ;
223
224
break ;
224
225
}
@@ -259,19 +260,18 @@ impl PyProcMesh {
259
260
}
260
261
}
261
262
262
- // Return with error if the mesh is unhealthy.
263
- async fn ensure_mesh_healthy (
264
- unhealthy_event : & Mutex < Option < Option < ProcEvent > > > ,
265
- ) -> Result < ( ) , PyErr > {
263
+ async fn ensure_mesh_healthy ( unhealthy_event : & Mutex < Unhealthy < ProcEvent > > ) -> Result < ( ) , PyErr > {
266
264
let locked = unhealthy_event. lock ( ) . await ;
267
- if let Some ( event) = & * locked {
268
- let msg = match event {
269
- Some ( e) => format ! ( "proc mesh is stopped with reason: {:?}" , e) ,
270
- None => "proc mesh is stopped with reason: alloc is stopped" . to_string ( ) ,
271
- } ;
272
- return Err ( SupervisionError :: new_err ( msg) ) ;
265
+ match & * locked {
266
+ Unhealthy :: SoFarSoGood => Ok ( ( ) ) ,
267
+ Unhealthy :: StreamClosed => Err ( SupervisionError :: new_err (
268
+ "proc mesh is stopped with reason: alloc is stopped" . to_string ( ) ,
269
+ ) ) ,
270
+ Unhealthy :: Crashed ( event) => Err ( SupervisionError :: new_err ( format ! (
271
+ "proc mesh is stopped with reason: {:?}" ,
272
+ event
273
+ ) ) ) ,
273
274
}
274
- Ok ( ( ) )
275
275
}
276
276
277
277
#[ pymethods]
0 commit comments