Skip to content

Commit fe4081f

Browse files
committed
fix(server): redrive staged configuration generations
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
1 parent 2643193 commit fe4081f

1 file changed

Lines changed: 43 additions & 8 deletions

File tree

crates/openshell-server/src/supervisor_session.rs

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2300,10 +2300,19 @@ async fn handle_supervisor_message(
23002300
state
23012301
.supervisor_sessions
23022302
.finalize_config_update(sandbox_id, session_id, &completed, false);
2303+
// Either projection can arrive first. Once the supervisor has
2304+
// staged one half, rebuild both current projections so the
2305+
// matching half and the deferred admission result are driven
2306+
// to a fixed point even when no further mutation occurs.
2307+
crate::config_delivery::publish_sandbox_components(
2308+
state,
2309+
sandbox_id,
2310+
crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER,
2311+
);
23032312
debug!(
23042313
sandbox_id,
23052314
session_id,
2306-
"supervisor configuration generation is waiting for its matching component"
2315+
"supervisor configuration generation is waiting for its matching component; scheduled reconciliation"
23072316
);
23082317
return;
23092318
}
@@ -3104,11 +3113,19 @@ mod tests {
31043113
}
31053114

31063115
#[tokio::test]
3107-
async fn generation_pending_result_is_not_persisted_or_suppressed() {
3116+
async fn generation_pending_result_schedules_reconciliation_without_persistence() {
31083117
use openshell_core::proto::{ConfigApplyFailure, ConfigurationAdmissionState};
31093118

31103119
let sandbox_id = "sb-generation-pending-retry";
31113120
let state = state_with_sandbox(sandbox_id).await;
3121+
let mut stored_sandbox = state
3122+
.store
3123+
.get_message::<Sandbox>(sandbox_id)
3124+
.await
3125+
.unwrap()
3126+
.expect("sandbox is persisted");
3127+
stored_sandbox.spec = Some(SandboxSpec::default());
3128+
state.store.put_message(&stored_sandbox).await.unwrap();
31123129
let (tx, mut rx) = mpsc::channel(4);
31133130
let (shutdown_tx, _shutdown_rx) = oneshot::channel();
31143131
state.supervisor_sessions.register(
@@ -3199,12 +3216,30 @@ mod tests {
31993216
.is_none(),
32003217
"a transient generation mismatch must not persist rejected admission"
32013218
);
3202-
assert_eq!(
3203-
state
3204-
.supervisor_sessions
3205-
.deliver_config(sandbox_id, message),
3206-
DeliveryDisposition::Enqueued
3207-
);
3219+
let redriven_components = tokio::time::timeout(Duration::from_secs(2), async {
3220+
let mut components = Vec::new();
3221+
while components.len() < 2 {
3222+
let Some(gateway_message::Payload::ConfigUpdate(update)) = rx
3223+
.recv()
3224+
.await
3225+
.expect("redriven configuration update")
3226+
.payload
3227+
else {
3228+
continue;
3229+
};
3230+
components.push(match update.component.expect("redriven component") {
3231+
config_update::Component::SandboxConfig(_) => ConfigComponent::SandboxConfig,
3232+
config_update::Component::ProviderEnvironment(_) => {
3233+
ConfigComponent::ProviderEnvironment
3234+
}
3235+
});
3236+
}
3237+
components
3238+
})
3239+
.await
3240+
.expect("generation mismatch schedules prompt reconciliation");
3241+
assert!(redriven_components.contains(&ConfigComponent::SandboxConfig));
3242+
assert!(redriven_components.contains(&ConfigComponent::ProviderEnvironment));
32083243
}
32093244

32103245
#[tokio::test]

0 commit comments

Comments
 (0)