Skip to main content

ModuleRuntime

Struct ModuleRuntime 

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

The per-run module state a deploy command carries: the target’s stored subscription plus the repo’s committed re-anchors. Built once per command (under the advisory lock, after the tracking tables are ensured), mutated only through its own methods so the in-memory view and the stored tables never diverge within a run.

Implementations§

Source§

impl ModuleRuntime

Source

pub fn established(&self) -> &BTreeSet<String>

The modules established on this target (base excluded). THE establishment source for every consumer.

Source

pub async fn load( pool: &PgPool, tracking_table: &TrackingTable, baselines_dir: &Path, ) -> Result<Self>

Load the stored subscription and the committed re-anchors. The consumed-through cursor is not loaded here — it is derived from the baseline main rows whenever the crossing loop needs it, so a pre-subscription target (rows but no _modules table yet) needs no special reconstruction: its provision baseline row seeds the cursor natively.

Source

pub fn adoption_baseline(&self) -> Option<(u64, &[MigrationSection])>

The baseline adoption reads content from: simply the highest-version committed baseline, re-anchor or not.

Provenance-cut sections make any committed baseline safe to adopt from, unconsumed re-anchors included: a re-anchor’s remap sections carry objects already present under the source’s old name, so per-section adoption records those as satisfied and runs only the plain sections plus remap sections whose source the target lacks — no collision, no routing around the re-anchor.

Source

pub fn needing_baseline_content<'a, I: IntoIterator<Item = &'a String>>( &self, modules: I, ) -> Vec<String>

Of modules, those not established here whose pre-baseline state lives in the adoption baseline (Self::adoption_baseline) — adopting them requires provision --modules (baseline content), not replay. Modules absent from it are younger: their whole (break-free) history is in the migrations and plain apply adopts them.

Source

pub async fn forecast_crossings( &self, migrations: &[ParsedMigration], ) -> Result<BTreeSet<String>>

The never-established modules this apply’s crossing sweep would SUBSCRIBE — a read-only forecast the apply adoption guard consults so it can ride a crossing instead of refusing toward provision. Thread a simulated subscription through every committed re-anchor above the derived cursor, in version order, using the exact wholeness evaluation the real loop uses ([evaluate_crossing] fed by [run_eligible]- filtered acquisition pairs). There is no second ordering or derivation path: this is a pure read-only replay of the same predicates the sweep applies, so its prediction cannot drift from what the sweep then does.

A module in the result (a brand-new module whose sources this target holds whole, at a split / modularization / merge crossing) needs NOTHING from the baseline — the crossing relabels objects already present. Modules NOT in the result the guard treats as before: baseline-content refusal if they need it, ordinary replay adoption otherwise. A wholeness membrane stops the walk (its own crossing and everything after are not forecast as subscribing); the real apply loop then surfaces that membrane — a needed-modules block always coincides with the blocked module having baseline content, so a named blocked module still gets the clean baseline-content refusal here, while an unnamed one (bare-source apply) reaches the membrane unpreempted.

No circularity: the evaluation reads only the stored subscription, the committed re-anchors, and the migration files’ acquisition sections — never the requested --modules selection.

Source

pub async fn cross_re_anchors_through( &mut self, ceiling: Option<u64>, ) -> Result<()>

The crossing loop. Consume, in version order, every committed re-anchor above the derived cursor and at or below ceiling (None = all of them — the end-of-apply sweep that makes a pure re-tag land on a fully-up-to-date target).

Single-shot gate+commit per re-anchor: only correct when nothing of those versions remains to run in this apply — i.e. for re-anchors strictly below the migration being processed, and for the final sweep. A re-anchor AT a pending migration’s version goes through the split Self::gate_re_anchor_at / Self::commit_crossing pair instead (two-phase): its acquisition delta lives in migration V itself, so wholeness only finalizes once V’s sections have run.

Source

pub async fn gate_re_anchor_at( &self, version: u64, acquirable: &BTreeSet<(Option<String>, Option<String>)>, ) -> Result<Option<PendingCrossing>>

Gate phase of the two-phase crossing: evaluate the re-anchor at exactly version (if one exists above the derived cursor) against the subscription, WITHOUT writing anything. The caller runs version V’s sections next and then calls Self::commit_crossing with the returned pending crossing. On wholeness failure this bails — the strong membrane: nothing at or after V may run.

Source

pub async fn commit_crossing(&mut self, pending: PendingCrossing) -> Result<()>

Commit phase of the two-phase crossing: rewrite the subscription through the gated re-anchor’s remaps and record the consumption in the ledger — one transaction (the caller holds the advisory lock). Runs after the version’s own sections completed (acquisition deltas live in migration V), so wholeness has finalized.

The consumption is a what-happened fact recorded like any other: the re-anchor’s own baseline main row (with its checksum), which seeds the derived cursor so the re-anchor is never re-evaluated, plus zero-trace satisfied section rows for exactly the remap sections the crossing relabeled — those whose source the target holds. Irrelevant sections (source not held) record nothing. Crossing ≠ mutation: an untouched subscription still records its consumption row (the main row names no modules, so it is always safe to write).

Source

pub async fn record_provisioned( &mut self, modules: &BTreeSet<String>, ) -> Result<()>

Record a fresh provision’s outcome: subscribe the provisioned modules. One transaction, under the caller’s advisory lock.

Provision never crosses. It seeds no cursor of its own: the baseline row provision already laid down (or none, on a baseline-free replay) IS the cursor seed — the derived cursor is the highest baseline version, so every re-anchor ≤ it is moot without any special step.

Source

pub async fn record_adopted(&mut self, modules: &BTreeSet<String>) -> Result<()>

Record an explicit adoption: subscribe each of modules not already subscribed (source = adopt). Idempotent for already-subscribed ones.

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more