pub trait CutoverParticipant: Send {
// Required method
fn name(&self) -> &str;
// Provided methods
fn owned_paths(&self) -> Vec<PathBuf> { ... }
fn prepare(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError> { ... }
fn quiesce(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError> { ... }
fn relocate(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError> { ... }
fn reopen(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError> { ... }
fn settle(
&mut self,
_cx: &CutoverContext,
_settlement: Settlement,
) -> Result<(), ParticipantError> { ... }
fn recover_completed(
&mut self,
_cx: &CutoverContext,
) -> Result<(), ParticipantError> { ... }
}Expand description
An opaque lifecycle participant: something the app owns that holds state under the root and must be stopped, moved, reopened or released as part of the cutover (an encrypted database and its key, a settings store, a resident service, a watcher).
Every hook has a default that does nothing, so a participant implements the ones it needs.
Hooks run in registration order (settle(Aborted) in reverse), on the caller’s thread, one at
a time. A panic in a hook is caught and reported as that hook failing.
Contract: prepare validates and acquires what the cutover needs and changes nothing the old
root depends on; quiesce stops this participant’s writers (after it returns Ok nothing of
this participant writes to the old root, and a read-only relocate may rely on it);
relocate copies this participant’s state to the new root, never modifies or removes the old
state, and must be idempotent (state already verified at the new root from an earlier attempt
is Ok); reopen opens the participant at the new root and verifies it; settle releases
what prepare acquired and, for Settlement::Aborted, resumes at the old root. settle is
called for every participant whose prepare returned Ok, whichever later hook failed, so it
must be safe in any state (a participant that quiesced and one that did not alike). A
participant whose own prepare failed is not settled: it cleans up after itself.
A phased database adapter maps prepare to prepare_relocation, quiesce to the session’s
quiesce, and relocate to copy. A committed copy does not activate the new database:
only this coordinator’s durable Switched record authorizes the session’s reopen.
settle(Committed) maps to RelocationSettlement::Committed cleanup; settle(Aborted) maps
to RelocationSettlement::Aborted, resumes the old database, and retains a committed copy.
A failed reopen never authorizes old-root resumption, even when no new connection was opened.
Recovery constructs fresh participants from durable root, file and transaction identities.
A Switched recovery calls reopen directly, without prepare, quiesce or relocate:
database adapters reconstruct a session with recover_relocation_session and retain it in
participant state. They must not use terminal recover_relocation, which clears replay
journals before this coordinator records Completed. Only settle(Committed), called after
that durable record, settles the retained session. Dropping it after a failed reopen or failed
completion-record write preserves recovery authority for another process.
An unknown copy/transaction outcome must preserve its journal
and both byte identities, return an error, and keep writers stopped until recovery resolves it.
Required Methods§
Provided Methods§
Sourcefn owned_paths(&self) -> Vec<PathBuf>
fn owned_paths(&self) -> Vec<PathBuf>
Paths, relative to the root, this participant moves by its own means. A tree move leaves
them out (MigrateOptions::exclude) and a companion list may not touch them.
fn prepare(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError>
fn quiesce(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError>
fn relocate(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError>
fn reopen(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError>
fn settle( &mut self, _cx: &CutoverContext, _settlement: Settlement, ) -> Result<(), ParticipantError>
Sourcefn recover_completed(
&mut self,
_cx: &CutoverContext,
) -> Result<(), ParticipantError>
fn recover_completed( &mut self, _cx: &CutoverContext, ) -> Result<(), ParticipantError>
Retry selected-new cleanup after durable Completed, including in a fresh process. Idempotent: absent already-clean state succeeds; retained unknown/mismatched authority fails. Never resumes old root. DB adapters use DB-owned completed recovery, rather than blindly reopening or treating a missing in-memory session as already settled.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".