fix: reject unavailable retained sessions

This commit is contained in:
2026-09-29 06:44:27 +09:00
parent ac7a6027bd
commit 08cbf93f7b
+22 -23
View File
@@ -153,7 +153,7 @@ async fn prepare_selected_worker(
} }
let observation = lifecycle.observe(&target).await?; let observation = lifecycle.observe(&target).await?;
apply_worker_session_observation(&mut target, observation.observation); apply_worker_session_observation(&mut target, observation.observation)?;
Ok(target) Ok(target)
} }
@@ -217,21 +217,19 @@ enum WorkerPickerResult {
fn apply_worker_session_observation( fn apply_worker_session_observation(
target: &mut client::BackendRuntimeTarget, target: &mut client::BackendRuntimeTarget,
observation: WorkerSessionAvailability, observation: WorkerSessionAvailability,
) { ) -> Result<(), io::Error> {
match observation { match observation {
WorkerSessionAvailability::LiveProtocol => {} WorkerSessionAvailability::LiveProtocol => Ok(()),
WorkerSessionAvailability::RetainedSnapshot { snapshot, .. } => { WorkerSessionAvailability::RetainedSnapshot { snapshot, .. } => {
target.initial_snapshot = Some(snapshot); target.initial_snapshot = Some(snapshot);
target.initial_notice = Some("read-only retained Session snapshot".to_string()); target.initial_notice = Some("read-only retained Session snapshot".to_string());
Ok(())
} }
WorkerSessionAvailability::Unavailable { message, .. } => { WorkerSessionAvailability::Unavailable { reason, message } => {
let bounded_message: String = message.chars().take(512).collect(); let message = message.chars().take(512).collect::<String>();
target.initial_snapshot = Some(protocol::SessionSnapshot { Err(io::Error::other(format!(
pending_submissions: protocol::PendingSubmissionsSnapshot::default(), "Backend Worker Session is unavailable: {reason:?}: {message}"
entries: Vec::new(), )))
});
target.initial_notice =
Some(format!("retained Session unavailable: {bounded_message}"));
} }
} }
} }
@@ -770,14 +768,15 @@ mod tests {
} }
#[test] #[test]
fn authoritative_observation_selects_live_retained_and_unavailable_detail_modes() { fn authoritative_observation_opens_only_live_or_retained_sessions() {
let mut live = client::BackendRuntimeTarget::new( let mut live = client::BackendRuntimeTarget::new(
"http://127.0.0.1:3000", "http://127.0.0.1:3000",
"workspace-a", "workspace-a",
"runtime-a", "runtime-a",
"worker-a", "worker-a",
); );
apply_worker_session_observation(&mut live, WorkerSessionAvailability::LiveProtocol); apply_worker_session_observation(&mut live, WorkerSessionAvailability::LiveProtocol)
.unwrap();
assert!(live.initial_snapshot.is_none()); assert!(live.initial_snapshot.is_none());
let snapshot = protocol::SessionSnapshot { let snapshot = protocol::SessionSnapshot {
@@ -795,25 +794,25 @@ mod tests {
}, },
snapshot: snapshot.clone(), snapshot: snapshot.clone(),
}, },
); )
.unwrap();
assert_eq!(retained.initial_snapshot, Some(snapshot)); assert_eq!(retained.initial_snapshot, Some(snapshot));
assert!(retained.initial_notice.unwrap().contains("read-only")); assert!(retained.initial_notice.unwrap().contains("read-only"));
let mut unavailable = live; let mut unavailable = live;
apply_worker_session_observation( let error = apply_worker_session_observation(
&mut unavailable, &mut unavailable,
WorkerSessionAvailability::Unavailable { WorkerSessionAvailability::Unavailable {
reason: client::WorkerSessionUnavailableReason::RetentionMissing, reason: client::WorkerSessionUnavailableReason::RetentionMissing,
message: "retention expired".to_string(), message: "retention expired".to_string(),
}, },
); )
assert!(unavailable.initial_snapshot.is_some()); .unwrap_err()
assert!( .to_string();
unavailable assert!(unavailable.initial_snapshot.is_none());
.initial_notice assert!(unavailable.initial_notice.is_none());
.unwrap() assert!(error.contains("RetentionMissing"));
.contains("retention expired") assert!(error.contains("retention expired"));
);
} }
#[test] #[test]