Require fresh State Anchor absence before lease release
This commit is contained in:
parent
4dd2b150d2
commit
3b76b59bdf
1 changed files with 543 additions and 194 deletions
|
|
@ -26,7 +26,10 @@ use crate::lifecycle::{
|
|||
SessionLifecycleAdapter,
|
||||
};
|
||||
use crate::network::NetworkCoordinator;
|
||||
use crate::runtime::{AwaitingAttachedRunsc, CommittedSandboxRuntime, SandboxCoordinator};
|
||||
use crate::runtime::{
|
||||
AwaitingAttachedRunsc, CommittedSandboxRuntime, SandboxCoordinator,
|
||||
StateAnchorAbsenceObservation,
|
||||
};
|
||||
use crate::state_anchor::{StateAnchorCoordinator, StateAnchorReleaseAuthority};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -80,6 +83,7 @@ pub struct ProductionLifecycleAdapter<'a> {
|
|||
runtime: Option<CommittedSandboxRuntime>,
|
||||
state_anchor_mount: Option<MountIdentity>,
|
||||
state_anchor_release: Option<StateAnchorReleaseAuthority>,
|
||||
state_anchor_absence: Option<StateAnchorAbsenceObservation>,
|
||||
}
|
||||
|
||||
pub type ProductionHostCoordinatorLifecycle<'store, 'resources> = HostCoordinatorLifecycle<
|
||||
|
|
@ -175,6 +179,7 @@ impl<'a> ProductionLifecycleAdapter<'a> {
|
|||
runtime: None,
|
||||
state_anchor_mount: None,
|
||||
state_anchor_release: None,
|
||||
state_anchor_absence: None,
|
||||
},
|
||||
ProductionSessionRegistry { registry },
|
||||
)
|
||||
|
|
@ -409,18 +414,26 @@ impl<'a> ProductionLifecycleAdapter<'a> {
|
|||
)
|
||||
.map_err(failure)?,
|
||||
);
|
||||
self.runtime
|
||||
let runtime = self
|
||||
.runtime
|
||||
.as_mut()
|
||||
.ok_or_else(|| ProductionLifecycleError("committed runtime is absent".into()))?
|
||||
.unmount_state_anchor(
|
||||
self.state_anchor_release
|
||||
.as_ref()
|
||||
.ok_or_else(|| {
|
||||
ProductionLifecycleError("State Anchor release is absent".into())
|
||||
})?
|
||||
.mount(),
|
||||
)
|
||||
.ok_or_else(|| ProductionLifecycleError("committed runtime is absent".into()))?;
|
||||
let release = self
|
||||
.state_anchor_release
|
||||
.as_ref()
|
||||
.ok_or_else(|| ProductionLifecycleError("State Anchor release is absent".into()))?;
|
||||
runtime
|
||||
.unmount_state_anchor(release.mount())
|
||||
.map_err(failure)?;
|
||||
self.state_anchor_absence = Some(
|
||||
runtime
|
||||
.observe_state_anchor_absence(
|
||||
release.user_namespace(),
|
||||
release.mount_namespace(),
|
||||
release.mount(),
|
||||
)
|
||||
.map_err(failure)?,
|
||||
);
|
||||
self.state_anchor_mount = None;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -428,11 +441,44 @@ impl<'a> ProductionLifecycleAdapter<'a> {
|
|||
fn release_prepared_lower(&mut self) -> Result<(), ProductionLifecycleError> {
|
||||
let release = self
|
||||
.state_anchor_release
|
||||
.take()
|
||||
.as_ref()
|
||||
.ok_or_else(|| ProductionLifecycleError("State Anchor release is absent".into()))?;
|
||||
self.state_anchor()
|
||||
.complete_release_after_unmount(&release, self.plan.state_anchor_layout)
|
||||
.map_err(failure)
|
||||
let first_observation = self.state_anchor_absence.ok_or_else(|| {
|
||||
ProductionLifecycleError("State Anchor absence evidence is absent".into())
|
||||
})?;
|
||||
let runtime = self
|
||||
.runtime
|
||||
.as_mut()
|
||||
.ok_or_else(|| ProductionLifecycleError("committed runtime is absent".into()))?;
|
||||
let coordinator = StateAnchorCoordinator::new(&self.plan.store, self.plan.catalog);
|
||||
coordinator
|
||||
.complete_release_after_unmount(
|
||||
release,
|
||||
self.plan.state_anchor_layout,
|
||||
first_observation,
|
||||
|| {
|
||||
runtime
|
||||
.observe_state_anchor_absence(
|
||||
release.user_namespace(),
|
||||
release.mount_namespace(),
|
||||
release.mount(),
|
||||
)
|
||||
.map_err(|error| {
|
||||
crate::state_anchor::StateAnchorCoordinatorError::InvalidState(
|
||||
match error {
|
||||
crate::runtime::SandboxCoordinatorError::InvalidState(
|
||||
detail,
|
||||
) => detail,
|
||||
_ => "Runtime Supervisor absence observation failed",
|
||||
},
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
.map_err(failure)?;
|
||||
self.state_anchor_release = None;
|
||||
self.state_anchor_absence = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn graceful_exit(&mut self) -> Result<(), ProductionLifecycleError> {
|
||||
|
|
|
|||
Loading…
Reference in a new issue