Skip to content

Commit b3a2e19

Browse files
committed
feat(container-runner): keep instance warm instead of self-exiting
1 parent 4a79659 commit b3a2e19

2 files changed

Lines changed: 15 additions & 16 deletions

File tree

container-runner/src/actor.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use tokio::sync::Mutex as TokioMutex;
1616
use crate::child::{ChildProcess, SpawnSpec, log_prefix};
1717
use crate::input::ActorInput;
1818
use 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
};

container-runner/src/main.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,12 @@ pub fn effective_stop_grace() -> Duration {
167167
}
168168
}
169169

170-
/// End the process. Called when the LAST actor on this instance is gone (or a
171-
/// failed start poisoned an otherwise idle instance): the instance drains
172-
/// instead of lingering for the next placement. The runner is PID 1 in the
170+
/// End the process. Only the platform shutdown signal drives this now: actors
171+
/// stopping or failing to start no longer exit the instance, so it stays warm
172+
/// and reusable and its logs have time to drain. The runner is PID 1 in the
173173
/// image, so exiting stops the container and the platform reaps the instance.
174174
pub fn request_exit(actor_id: &str, reason: &str) {
175-
tracing::info!(actor_id = %actor_id, reason, "actor finished, exiting container");
175+
tracing::info!(actor_id = %actor_id, reason, "shutting down container");
176176
EXIT.cancel();
177177
}
178178

0 commit comments

Comments
 (0)