@@ -46,6 +46,7 @@ use crate::mailbox::PyMailbox;
46
46
use crate :: runtime:: signal_safe_block_on;
47
47
use crate :: shape:: PyShape ;
48
48
use crate :: supervision:: SupervisionError ;
49
+ use crate :: supervision:: Unhealthy ;
49
50
50
51
// A wrapper around `ProcMesh` which keeps track of all `RootActorMesh`s that it spawns.
51
52
pub struct TrackedProcMesh {
@@ -119,7 +120,7 @@ pub struct PyProcMesh {
119
120
proc_events : SharedCell < Mutex < ProcEvents > > ,
120
121
user_monitor_receiver : SharedCell < Mutex < mpsc:: UnboundedReceiver < ProcEvent > > > ,
121
122
user_monitor_registered : Arc < AtomicBool > ,
122
- unhealthy_event : Arc < Mutex < Option < Option < ProcEvent > > > > ,
123
+ unhealthy_event : Arc < Mutex < Unhealthy < ProcEvent > > > ,
123
124
}
124
125
125
126
fn allocate_proc_mesh ( alloc : & PyAlloc ) -> PyResult < PyPythonTask > {
@@ -146,15 +147,15 @@ impl PyProcMesh {
146
147
let proc_events = SharedCell :: from ( Mutex :: new ( proc_mesh. events ( ) . unwrap ( ) ) ) ;
147
148
let ( user_sender, user_receiver) = mpsc:: unbounded_channel :: < ProcEvent > ( ) ;
148
149
let user_monitor_registered = Arc :: new ( AtomicBool :: new ( false ) ) ;
149
- let unhealthy_event = Arc :: new ( Mutex :: new ( None ) ) ;
150
+ let unhealthy_event = Arc :: new ( Mutex :: new ( Unhealthy :: SoFarSoGood ) ) ;
150
151
let monitor = tokio:: spawn ( Self :: default_proc_mesh_monitor (
151
152
proc_events
152
153
. borrow ( )
153
154
. expect ( "borrowing immediately after creation" ) ,
154
155
world_id,
155
156
user_sender,
156
- user_monitor_registered . clone ( ) ,
157
- unhealthy_event . clone ( ) ,
157
+ Arc :: clone ( & user_monitor_registered ) ,
158
+ Arc :: clone ( & unhealthy_event ) ,
158
159
) ) ;
159
160
Self {
160
161
inner : SharedCell :: from ( TrackedProcMesh :: from ( proc_mesh) ) ,
@@ -172,7 +173,7 @@ impl PyProcMesh {
172
173
world_id : WorldId ,
173
174
user_sender : mpsc:: UnboundedSender < ProcEvent > ,
174
175
user_monitor_registered : Arc < AtomicBool > ,
175
- unhealthy_event : Arc < Mutex < Option < Option < ProcEvent > > > > ,
176
+ unhealthy_event : Arc < Mutex < Unhealthy < ProcEvent > > > ,
176
177
) {
177
178
loop {
178
179
let mut proc_events = events. lock ( ) . await ;
@@ -181,15 +182,15 @@ impl PyProcMesh {
181
182
let mut inner_unhealthy_event = unhealthy_event. lock( ) . await ;
182
183
match event {
183
184
None => {
184
- * inner_unhealthy_event = Some ( None ) ;
185
+ * inner_unhealthy_event = Unhealthy :: StreamClosed ;
185
186
tracing:: info!( "ProcMesh {}: alloc has stopped" , world_id) ;
186
187
break ;
187
188
}
188
189
Some ( event) => match event {
189
190
// Graceful stops can be ignored.
190
191
ProcEvent :: Stopped ( _, ProcStopReason :: Stopped ) => continue ,
191
192
event => {
192
- * inner_unhealthy_event = Some ( Some ( event. clone( ) ) ) ;
193
+ * inner_unhealthy_event = Unhealthy :: Crashed ( event. clone( ) ) ;
193
194
tracing:: info!( "ProcMesh {}: {}" , world_id, event) ;
194
195
if user_monitor_registered. load( std:: sync:: atomic:: Ordering :: SeqCst ) {
195
196
if user_sender. send( event) . is_err( ) {
@@ -202,7 +203,7 @@ impl PyProcMesh {
202
203
}
203
204
_ = events. preempted( ) => {
204
205
let mut inner_unhealthy_event = unhealthy_event. lock( ) . await ;
205
- * inner_unhealthy_event = Some ( None ) ;
206
+ * inner_unhealthy_event = Unhealthy :: StreamClosed ;
206
207
tracing:: info!( "ProcMesh {}: is stopped" , world_id) ;
207
208
break ;
208
209
}
@@ -243,19 +244,18 @@ impl PyProcMesh {
243
244
}
244
245
}
245
246
246
- // Return with error if the mesh is unhealthy.
247
- async fn ensure_mesh_healthy (
248
- unhealthy_event : & Mutex < Option < Option < ProcEvent > > > ,
249
- ) -> Result < ( ) , PyErr > {
247
+ async fn ensure_mesh_healthy ( unhealthy_event : & Mutex < Unhealthy < ProcEvent > > ) -> Result < ( ) , PyErr > {
250
248
let locked = unhealthy_event. lock ( ) . await ;
251
- if let Some ( event) = & * locked {
252
- let msg = match event {
253
- Some ( e) => format ! ( "proc mesh is stopped with reason: {:?}" , e) ,
254
- None => "proc mesh is stopped with reason: alloc is stopped" . to_string ( ) ,
255
- } ;
256
- return Err ( SupervisionError :: new_err ( msg) ) ;
249
+ match & * locked {
250
+ Unhealthy :: SoFarSoGood => Ok ( ( ) ) ,
251
+ Unhealthy :: StreamClosed => Err ( SupervisionError :: new_err (
252
+ "proc mesh is stopped with reason: alloc is stopped" . to_string ( ) ,
253
+ ) ) ,
254
+ Unhealthy :: Crashed ( event) => Err ( SupervisionError :: new_err ( format ! (
255
+ "proc mesh is stopped with reason: {:?}" ,
256
+ event
257
+ ) ) ) ,
257
258
}
258
- Ok ( ( ) )
259
259
}
260
260
261
261
#[ pymethods]
0 commit comments