Skip to main content

CutoverParticipant

Trait CutoverParticipant 

Source
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§

Source

fn name(&self) -> &str

A short stable name: ASCII letters, digits, ., _ or -, unique within the cutover.

Provided Methods§

Source

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.

Source

fn prepare(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError>

Source

fn quiesce(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError>

Source

fn relocate(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError>

Source

fn reopen(&mut self, _cx: &CutoverContext) -> Result<(), ParticipantError>

Source

fn settle( &mut self, _cx: &CutoverContext, _settlement: Settlement, ) -> Result<(), ParticipantError>

Source

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".

Implementors§