Run non-interactive sessions through production coordination

This commit is contained in:
ms2k 2026-07-16 16:28:18 +09:00
commit 71b0266cf2

View file

@ -293,15 +293,37 @@ where
/// # Errors
/// Returns the first invalid transition, durable update, or production adapter failure.
pub fn bootstrap_new_domain_while_owner_live(
&mut self,
generation: Generation,
session: Session,
owner_live: impl FnMut() -> bool,
) -> Result<bool, LifecycleError<A::Error>> {
self.bootstrap_new_domain_while_owner_live_and_service(
generation,
session,
owner_live,
|_| Ok(()),
|_| Ok(()),
)
}
/// Drives cold start while servicing bounded pre-publication waiters between actions.
///
/// # Errors
/// Returns the first invalid transition, durable update, adapter, or waiter-service failure.
pub fn bootstrap_new_domain_while_owner_live_and_service(
&mut self,
generation: Generation,
session: Session,
mut owner_live: impl FnMut() -> bool,
mut service_waiters: impl FnMut(&mut Self) -> Result<(), A::Error>,
mut withdraw_waiter_admission: impl FnMut(&mut Self) -> Result<(), A::Error>,
) -> Result<bool, LifecycleError<A::Error>> {
let session_id = session.session_id;
self.start_new_domain(generation, session)?;
macro_rules! checkpoint {
() => {
service_waiters(self).map_err(LifecycleError::Adapter)?;
if !owner_live() {
self.disconnect_session(session_id)?;
return Ok(false);
@ -327,6 +349,11 @@ where
checkpoint!();
self.start_sandbox()?;
checkpoint!();
withdraw_waiter_admission(self).map_err(LifecycleError::Adapter)?;
if !owner_live() {
self.disconnect_session(session_id)?;
return Ok(false);
}
self.publish_domain()?;
Ok(true)
}
@ -750,6 +777,48 @@ where
})
}
/// Performs the complete ordered normal teardown when the final session has disconnected.
///
/// # Errors
/// Returns the first physical or durable teardown failure.
pub fn teardown_if_idle(&mut self) -> Result<bool, LifecycleError<A::Error>> {
if !self.is_teardown_ready() {
return Ok(false);
}
self.begin_teardown()?;
self.stop_sandbox()?;
self.stop_sidecar()?;
self.unmount_state_anchor()?;
self.release_prepared_lower_lease()?;
self.graceful_supervisor_exit()?;
self.finish_teardown()?;
Ok(true)
}
/// Transfers a published cold-start owner's lifetime edge to exact control admission.
///
/// # Errors
/// Refuses an unpublished Domain, unknown owner, or durable disconnect/teardown failure.
pub fn reconcile_published_bootstrap_owner(
&mut self,
session_id: SessionId,
bootstrap_owner_live: bool,
) -> Result<(), LifecycleError<A::Error>> {
Self::require(
LifecycleAction::DisconnectSession,
self.phase == DomainPhase::Ready && self.published,
"Domain is not published",
)?;
let phase = self
.session(session_id, LifecycleAction::DisconnectSession)?
.session_phase;
if phase == SessionPhase::Waiting && !bootstrap_owner_live {
self.disconnect_session(session_id)?;
self.teardown_if_idle()?;
}
Ok(())
}
/// # Errors
/// Refuses while any session retains Domain interest.
pub fn begin_teardown(&mut self) -> Result<(), LifecycleError<A::Error>> {