Supervise boot services with uniform five-second upgrade grace
This commit is contained in:
@@ -178,6 +178,56 @@ async fn stop_runs_hook() {
|
||||
assert_eq!(std::fs::read(world.0.join("stopped")).unwrap(), b"yes");
|
||||
host.stop().await;
|
||||
}
|
||||
/// PROTOCOL 3.7: an idle SDK listener opts into drain and exits before EOF/grace.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn superseded_idle_listener_drains_before_grace() {
|
||||
let world = TestWorld::new();
|
||||
let host = world.start().await;
|
||||
let (notice, mut notices) = tokio::sync::mpsc::unbounded_channel();
|
||||
host.register_native(
|
||||
"other",
|
||||
std::sync::Arc::new(move |_, method, _| {
|
||||
let notice = notice.clone();
|
||||
Box::pin(async move {
|
||||
assert_eq!(method, "superseded");
|
||||
notice.send(std::time::Instant::now()).unwrap();
|
||||
Ok(json!({}))
|
||||
})
|
||||
}),
|
||||
);
|
||||
let pid = call(&host, "probe.drain_service", json!({})).await;
|
||||
// Replace with a different real component; force only skips unrelated test consumers.
|
||||
std::fs::copy(
|
||||
fixtures().join("notes.wasm"),
|
||||
world.0.join("state/next.wasm"),
|
||||
)
|
||||
.unwrap();
|
||||
call(
|
||||
&host,
|
||||
"core.activate",
|
||||
json!({"plugin":"probe","wasm":"/state/next.wasm","force":true}),
|
||||
)
|
||||
.await;
|
||||
// Activation preparation/discovery is outside upgrade grace. Time from the
|
||||
// hook's outgoing call, not from the start of candidate compilation.
|
||||
let before = tokio::time::timeout(Duration::from_secs(60), notices.recv())
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
// Waiting on its lifetime lock is an exit event, not process-liveness polling.
|
||||
call(&host, "core.lock", json!({"path":"/drain-owner"})).await;
|
||||
assert!(before.elapsed() < Duration::from_secs(5));
|
||||
assert!(!host.processes().contains_key(pid.as_str().unwrap()));
|
||||
assert!(
|
||||
!world
|
||||
.0
|
||||
.join(format!("stopped-{}", pid.as_str().unwrap()))
|
||||
.exists(),
|
||||
"drain must not run on_stop (discovery processes may run their own hooks)"
|
||||
);
|
||||
host.stop().await;
|
||||
}
|
||||
|
||||
/// SDK framing carries payloads above 64 KiB in both directions.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn large_messages() {
|
||||
|
||||
Reference in New Issue
Block a user