Skip to main content

RootCutover

Struct RootCutover 

Source
pub struct RootCutover { /* private fields */ }
Expand description

The cutover of one app root. Build it with RootCutover::new, register participants, run it.

Implementations§

Source§

impl RootCutover

Source

pub fn new(app: AppRoot, old_root: impl Into<PathBuf>) -> Self

A cutover of app’s root (the new root) from old_root. old_root must be an absolute path to a real directory that does not contain, and is not inside, the new root.

Source

pub fn fs_move(self, fs_move: FsMove) -> Self

How the files travel (default FsMove::None).

Source

pub fn tree_roots( self, resolver: impl Fn(&CutoverContext) -> Result<Vec<PathBuf>, ParticipantError> + Send + 'static, ) -> Self

Resolve a bounded tree-root descriptor after every writer has quiesced. Legal only for FsMove::Tree without static include_roots.

Source

pub fn participant(self, participant: impl CutoverParticipant + 'static) -> Self

Register a participant. Order matters: hooks run in registration order.

Source

pub fn status(app: &AppRoot) -> Result<Option<RootStatus>, CutoverError>

The persisted selection of app’s root, or None when no cutover ever started there (the old root is the only root). Takes no lock and changes nothing. An unreadable record is an error, never a guess.

Source

pub fn selected_root( app: &AppRoot, legacy: &Path, ) -> Result<PathBuf, CutoverError>

The root to open: the new root once the switch is durable, otherwise legacy (the old root the app used before any cutover).

Source

pub fn run(&mut self) -> Result<CutoverReport, CutoverError>

Run the cutover. Idempotent: a completed cutover returns already_completed; a switched one is finished (the roll-forward of recover); an aborted or interrupted one is attempted again with the next generation.

On Err before the switch the old root is the authority and every prepared participant was settled as aborted. CutoverError::ReopenPending and CutoverError::Undecided mean the opposite or unknown: call recover. CutoverError::SettlementPending preserves new-root authority & retries cleanup only.

Source

pub fn recover(&mut self) -> Result<RecoverOutcome, CutoverError>

Finish a switched cutover after a restart or a failed reopen, without starting a new one. Run it at startup, before opening any root: it takes the cutover lock, resolves pending file transactions, and, when the record says switched, reopens every participant at the new root and completes. completed with pending settlement invokes only CutoverParticipant::recover_completed, never reopen or old-root resumption. A cutover that never reached the switch is left alone (RecoverOutcome::Nothing: the old root is still the authority).

Source

pub fn retire_old_root( app: &AppRoot, mode: RetireMode, ) -> Result<Retired, CutoverError>

Retire the old root of a completed cutover: a separate, identity-checked step that never runs as part of run. Refuses unless the record is completed and the directory at the recorded old path still has the file identity recorded when the cutover started (a path that was replaced is CutoverError::PathSubstituted, never touched), and the new root still has its recorded identity. Takes the cutover lock.

It never deletes: RetireMode::RenameAside renames the old root beside itself, RetireMode::Trash uses the platform trash. A crash between the rename and the record is repaired by calling it again (the aside directory is found by name and identity).

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.