@@ -16,7 +16,7 @@ use tokio::sync::Mutex as TokioMutex;
1616use crate :: child:: { ChildProcess , SpawnSpec , log_prefix} ;
1717use crate :: input:: ActorInput ;
1818use crate :: {
19- children, effective_stop_grace, release_child_port, request_exit , reserve_child_port,
19+ children, effective_stop_grace, release_child_port, reserve_child_port,
2020 runner_config,
2121} ;
2222
@@ -40,11 +40,12 @@ impl GameServer {
4040 release_child_port ( child. child_port ) . await ;
4141 }
4242
43- // Once the last actor is gone the instance drains rather than
44- // lingering for the next placement.
45- if children ( ) . is_empty ( ) {
46- request_exit ( actor_id, reason) ;
47- }
43+ // The instance stays alive and warm after its last actor stops, ready to
44+ // host the next placement. It is reaped by the platform's own shutdown
45+ // signal, not by self-exit. This keeps the serverless container long
46+ // lived enough for the log agent to drain its stderr, which a fast
47+ // self-exit could otherwise lose.
48+ tracing:: info!( actor_id = %actor_id, reason, "actor stopped, keeping instance warm" ) ;
4849 }
4950}
5051
@@ -129,12 +130,10 @@ impl Actor for GameServer {
129130 Ok ( child) => Arc :: new ( child) ,
130131 Err ( err) => {
131132 release_child_port ( child_port) . await ;
132- // A failed start on an otherwise idle instance poisons it;
133- // don't let it serve the next placement. With other actors
134- // running, the failure is this actor's alone.
135- if children ( ) . is_empty ( ) {
136- request_exit ( & actor_id, "child failed to start" ) ;
137- }
133+ // A failed start is this actor's alone and does not take the
134+ // instance down. The container stays warm and ready for the next
135+ // placement, and stays alive long enough for the log agent to
136+ // drain the failure logs before the platform reaps it.
138137 return Err ( err) ;
139138 }
140139 } ;
0 commit comments