feat(supervisor): supervisor task with state machine

One async task per managed server owns all state transitions via a
tokio::select! loop over cmd_rx and wait_child. Includes RealSpawner
and a smoke test covering the Start → Running → exit → Stopped →
Shutdown happy path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 11:44:12 +02:00
co-authored by Claude Sonnet 4.6
parent f1b2306156
commit a3c979511e
3 changed files with 376 additions and 10 deletions
+3 -10
View File
@@ -135,11 +135,7 @@ pub struct LogSink {
}
impl LogSink {
pub fn new(
server_name: String,
writer: RotatingLogWriter,
ring_capacity_bytes: usize,
) -> Self {
pub fn new(server_name: String, writer: RotatingLogWriter, ring_capacity_bytes: usize) -> Self {
let (tx, _) = broadcast::channel(LOG_BROADCAST_CAP);
Self {
server_name,
@@ -183,8 +179,8 @@ fn now_unix_ms() -> u64 {
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
use std::io::Read;
use tempfile::tempdir;
#[test]
fn writes_lines_with_tags() {
@@ -194,10 +190,7 @@ mod tests {
w.write_line("[out]", "hello").unwrap();
w.write_line("[err]", "boom").unwrap();
let mut s = String::new();
File::open(&base)
.unwrap()
.read_to_string(&mut s)
.unwrap();
File::open(&base).unwrap().read_to_string(&mut s).unwrap();
assert_eq!(s, "[out] hello\n[err] boom\n");
}