Skip to main content

UpgradeFromEntry

Struct UpgradeFromEntry 

Source
pub struct UpgradeFromEntry {
    pub from: String,
    pub instructions: Vec<UpgradeInstruction>,
}
Expand description

One upgrade entry: the prior version we’re upgrading from, plus the instruction sequence to execute.

Fields§

§from: String

Semver of the prior version. Authored as a literal string; validated lazily by UpgradeFromEntry::validate.

§instructions: Vec<UpgradeInstruction>

Ordered list of instructions to execute. Empty list = “no-op upgrade” (rare; usually means only documentation changed).

Implementations§

Source§

impl UpgradeFromEntry

Source

pub fn prior_versao(&self) -> &str

Prior-versao semver-2 literal this entry declares an upgrade path from — the string the OTP-shape release_handler:install_release/1 analog matches the running caixa’s :versao against at hot- upgrade dispatch time to pick this entry’s :instructions sequence. Returned byte-for-byte from the typed slot’s own String storage; no cloning, no re-parsing.

The M2 companion of the closed M3 mesh-slot scalar-accessor family — sibling in shape to crate::Membro::versao_requirement (a40b0e3), crate::Membro::nome (4a32abf), and the [crate::WitContract::{source, destination, world_ref}] (7f0fd43 / 0804823) / [crate::Entrada::{hostname, destination}] (11f3dfe / 6db982c) &str accessors already routing every per-mesh-slot-atom scalar-value axis through one typed dispatch on the substrate primitive — extended here onto the first per- M2-slot scalar-value axis. Every downstream consumer of the M2 :upgrade-from :from axis (the UpgradeFromEntry::validate SemVer-2 parse gate, the validate_upgrade_from cross-entry duplicate-detection re-parse assertion, the validate_upgrade_from_against_versao precedence gate, the validate_upgrade_from_against_behavior state-change- callback coherence gate, every per-arm error variant carrying the offending :from verbatim for feira lint rendering) now reads through this one accessor rather than open-coding &self.from / &entry.from / self.from.clone() / entry.from.clone().

A future extension of the axis (an M4 typed :from-range slot composing multiple prior versions into one entry, an operator- side pre-parsed semver::Version cache the accessor could materialize behind the same &str return contract, a per- cluster :placement-scoped prior-versao overlay the caixa-operator reconciles ahead of dispatch) migrates as a single caixa-core edit rather than a coordinated rewrite of the four validate-side call sites + every downstream error- variant carrying :from.

Source

pub fn instructions(&self) -> &[UpgradeInstruction]

Substrate-canonical per-:upgrade-from :instructions OTP-appup migration-instruction-list slice-return accessor every per-entry instructions-list reader keys off — returns the author-declared :instructions list verbatim as a &[UpgradeInstruction] slice-view over the same backing buffer the raw self.instructions.as_slice() field access borrows from. Non-optional: an empty slice is the load-bearing “author declared :instructions ()” sentinel — the Vec<UpgradeInstruction>::default()-produced empty tail the UpgradeFromEntry::instructions field’s own docstring already names as the “no-op upgrade” shape (a metadata-only upgrade entry — the operator’s :from-match dispatch matches the entry but runs no instructions, advancing straight to the “traffic swap” step) and every peer within-entry cross-instruction gate no-ops against without allocating a new Vec per gate.

The :upgrade-from :instructions slot carries the per-:from OTP-appup ordered instruction list the wasm-operator’s hot- upgrade dispatch materializes one per-instruction runtime primitive from — the Erlang/OTP appup’s per-{from, to, UpgradeInstructions, DowngradeInstructions} entry’s UpgradeInstructions list (code:load_module/1 / gen_server:code_change/3 / code:soft_purge/1 / code:purge/1 / restart_new_emulator — see INSPIRATIONS §II.4), projected through the tatara-lisp :upgrade-from ((:from … :instructions …)) author surface onto a typed Vec<UpgradeInstruction> whose per-element variant is UpgradeInstruction::LoadModule / UpgradeInstruction::StateChange / UpgradeInstruction::SoftPurge / UpgradeInstruction::Purge / UpgradeInstruction::Restart. Every downstream consumer that fans on the per-entry instruction list keys off this slice (the UpgradeFromEntry::validate per-instruction shape-check fan-out, the seven paired within-entry cross- instruction gates Self::validate_restart_exclusive / Self::validate_state_change_ordering / Self::validate_purge_ordering / Self::validate_state_change_before_cleanup / Self::validate_load_singularity / Self::validate_state_change_singularity / Self::validate_cleanup_singularity, the layout-side crate::layout::StandardLayout’s per-:state-change script-existence fan-out (crate::layout::LayoutError::MissingEntry’s LAYOUT_MISSING_ENTRY_KIND_UPGRADE_SCRIPT arm), the cross-slot validate_upgrade_from_against_behavior gate’s per-entry :state-change-instruction detection loop, every future wasm-operator (M2.5) per-:from-match hot-upgrade dispatch’s per-instruction runtime-primitive fan-out, every future M4 mesh.pleme.io/v1alpha1/Caixa CR materializer’s per-entry upgrade-plan admission-webhook fan-out).

Prior to this lift the .instructions Vec<UpgradeInstruction> was accessed inline at nine production sites across caixa-core/src/upgrade.rs and caixa-core/src/layout.rs — the UpgradeFromEntry::validate per-instruction shape-check fan-out (for instr in &self.instructions), the paired Self::validate_restart_exclusive restart-count / other-kind projections + .len() probe (three raw-access sites in one gate), the Self::validate_state_change_ordering / Self::validate_purge_ordering / Self::validate_state_change_before_cleanup / Self::validate_load_singularity / Self::validate_state_change_singularity / Self::validate_cleanup_singularity within-entry cross- instruction gate traversal heads, the peer validate_upgrade_from_against_behavior cross-slot composition gate’s for instr in &entry.instructions per-entry :state-change detection loop, and the crate::layout::StandardLayout-side for instr in &entry.instructions per-:state-change script-existence fan-out — nine open-coded field-accesses that expressed no compile-time link back to the typed slot. A future extension of the :instructions axis to a richer author surface (a per-cluster overlay the operator pins through a future :upgrade-from :instructions-overrides slot so a canary cluster runs a (:state-change …) before the production fleet does, a per-tenant instruction-list overlay the M4 CR materializer resolves per-CR to inject cluster- specific (:soft-purge …) cooldown adjustments, a promotion of the plain Vec<UpgradeInstruction> to a richer {static, dynamic} partition once virtual-actor-style dynamic-instruction composition (an operator-derived (:load-module …) sequence computed from the running module set at upgrade time) comes into typed scope, a per-instruction pre-condition scalar the future adaptive- upgrade engine reads to bias per-instruction retry strategy) would have had to be threaded through all nine open-coded copies in lockstep or one consumer would silently disagree with the peers on which instruction sequence a given :upgrade-from entry resolves to — the per- instruction shape-check reading the raw slot while the paired within-entry ordering gates read an operator-resolved slot would silently split the build-time per-entry gate cohort from the layout-side script-existence gate + the cross-slot behavior-composition gate + the runtime hot- upgrade dispatch, a nine-consumer split across the seven within-entry cross-instruction gates + the layout invariant + the cross-slot composition gate far from the source caixa.lisp with no field naming the instruction-sequence- drift root cause. Lifting the resolution rule to a typed method on the substrate primitive means every downstream consumer of the per-entry OTP-appup instruction-list surface reaches for exactly one typed dispatch — the resolver’s accept-set migrates as a unit on any future axis addition.

Fifth slice-return (&[T]) accessor on any M2 or M3 typed slot — sibling to the seed M2 crate::SupervisorSpec::children (bc92bce) &[ChildSpec] accessor on the peer per-:supervisor static-child-list Vec-carry axis, the M3 crate::Placement::clusters (a6e18d7) &[String] accessor on the peer per-:placement distribution-target-list Vec-carry axis, the M3 crate::AplicacaoSpec::membros (6c77e36) &[Membro] accessor on the peer per-:membros node-list Vec-carry axis, and the M3 crate::AplicacaoSpec::contratos (0dcc926) &[WitContract] accessor on the peer per- :contratos edge-list Vec-carry axis. This lift closes the last unlifted Vec-carry axis on any M2 or M3 typed slot in the substrate — the four peer axes named in the crate::SupervisorSpec::children seed docstring (Placement::clusters, AplicacaoSpec::membros, AplicacaoSpec::contratos, UpgradeFromEntry::instructions) are now all closed. The per-UpgradeFromEntry type carried two axes: the scalar Copy-return UpgradeFromEntry::prior_versao (75d27a8) on the :from axis, and now the slice-return UpgradeFromEntry::instructions on the peer :instructions axis. Named instructions() to match the storage field’s name verbatim and the tatara-lisp author-surface term (:instructions) the field’s own docstring already carries; the accessor’s identity maps onto the canonical OTP-appup vocabulary the crate::upgrade module doc already reaches for (“runs the instructions in order”). Returns &[UpgradeInstruction] (not &Vec<UpgradeInstruction>) because every downstream consumer of the instruction list treats it as a read-only sequence — the slice-view is the narrowest borrow that supports every present + roadmapped consumer (.iter(), .len(), .filter(...).count()) without leaking the backing Vec’s grow/push/reserve surface that no consumer of the typed view reaches for (the storage-side Vec remains reachable through the pub instructions field for the mutation-carrying Serialize/Deserialize derive round-trip and per-test fixture-mutation paths).

Source

pub fn validate(&self) -> Result<(), UpgradeError>

Verify the :from field is a valid semver, every instruction’s typed shape, the within-entry (:restart)-exclusivity invariant (an entry containing (:restart) must contain exactly one (:restart) and nothing else — see Self::validate_restart_exclusive), the within-entry state-change-ordering invariant (every (:state-change …) must be preceded by a (:load-module …) — see Self::validate_state_change_ordering), the within-entry purge-ordering invariant (every (:soft-purge …) / (:purge …) must be preceded by a (:load-module …) — see Self::validate_purge_ordering), the within-entry state-change-before-cleanup ordering invariant (no (:state-change …) may appear after any (:soft-purge …) / (:purge …) — see Self::validate_state_change_before_cleanup), the within- entry load-singularity invariant (no module appears as the target of (:load-module …) more than once — see Self::validate_load_singularity), the within-entry state-change-singularity invariant (no script appears as the target of (:state-change …) more than once — see Self::validate_state_change_singularity), and the within- entry cleanup-singularity invariant (no module appears as the target of (:soft-purge …) or (:purge …) more than once total — see Self::validate_cleanup_singularity).

Trait Implementations§

Source§

impl Clone for UpgradeFromEntry

Source§

fn clone(&self) -> UpgradeFromEntry

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for UpgradeFromEntry

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for UpgradeFromEntry

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Eq for UpgradeFromEntry

Source§

impl PartialEq for UpgradeFromEntry

Source§

fn eq(&self, other: &UpgradeFromEntry) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for UpgradeFromEntry

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for UpgradeFromEntry

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.