Skip to main content

Engine

Enum Engine 

Source
pub enum Engine {
    Znippy,
}
Expand description

A storage engine this binary actually carries.

The variants are #[cfg]-gated on purpose: a value of this type is proof that the engine it names is linked. There is no “selected but absent” state to guard against, because it cannot be represented.

Variants§

§

Znippy

znippy-plugin-git — Arrow-IPC in a znippy archive.

Implementations§

Source§

impl Engine

Source

pub const COMPILED: &'static [Engine]

Every engine compiled into this binary, in preference order.

Source

pub fn name(self) -> &'static str

The name this engine is selected by and reported under.

Source

pub fn replication_can_read_repositories(self) -> bool

Can replication read a repository this engine stores?

It reads one by opening it as a filesystem git repository — gix::open in [crate::mirror], then gunnar-client’s send-pack, which is proven against the real git receive-pack and must not be twinned. An engine that writes no .git layout cannot be read that way, and the failure lands inside the retry loop where nobody sees it: the server accepts every push and the standby stays empty.

So it is asked at start-up instead, and a server that cannot do what it was configured to do refuses to come up. Closing the gap means a server-side send-pack over GitServe — the store already emits packs for upload-pack — at which point this predicate goes away rather than gaining an arm.

Source

pub fn plugin(self) -> &'static str

The engine’s crate, as it is named on the Storage page and linked.

Source

pub fn summary(self) -> &'static str

What it stores and how, in one line — the Storage page’s tooltip.

Source

pub fn repo_url(self) -> String

Where the engine’s source lives, off NORDISK_REPOS: znippy’s own repository; storage-git-gix is a crate of edda’s (built on gitoxide’s gix-odb / gix-ref).

Source

pub fn report(self) -> StorageEngine

The engine, in parts — name, one-line description, source repository — for Admin.StorageInfo’s engine (2026-10-02).

Source

pub fn describe(self) -> String

What answers, in one line, for an operator reading storage info: znippy-plugin-git (Arrow-IPC archive; objects + refs), made of the same parts Self::report sends apart.

Source

pub fn compiled_list() -> String

The engines this binary carries, as a human-readable list.

Source

pub fn from_name(name: &str) -> Result<Engine>

Resolve a name to an engine, or refuse.

Three outcomes, and the middle one is the whole point:

  • a name this build carries → that engine;
  • a name this build knows but did not compile in → refused, saying so;
  • anything else → refused as unknown.

Never a fallback. See the module docs.

Source

pub fn selected() -> Result<Engine>

The engine this process runs, decided once, on the startup path.

ENGINE_ENV if it is set and non-empty, DEFAULT_ENGINE otherwise. An unset variable is not “no engine”: it is the default, which is znippy wherever znippy is compiled in.

Source

pub fn open_repo(self, git_dir: &Path, hash_kind: Kind) -> Result<Arc<OpenRepo>>

Open — creating if absent — the repository at git_dir.

Unconditional. “It holds nothing yet” is the normal state of a repository’s first push, not a reason to answer with something else: gating on what a repository already holds is what refuses every first push, which is a mistake this seam has already made once.

Source

pub fn cancel_index(self, git_dir: &Path)

Stop any index work on the repository at git_dir — the engine half of repo delete. A no-op for an engine without a background indexer.

Source

pub fn index_progress(self) -> Vec<(PathBuf, IndexSnapshot)>

Index work in flight across every open repository, as (git_dir, snapshot). Empty for an engine without a background indexer.

Source

pub fn explode_use(self) -> Vec<(PathBuf, ExplodeBand)>

Every open repository’s explode band, as (git_dir, band).

The exploded tier is a read cache with a byte budget, not storage: a blob is written into it by the first reader that inflates it and unlinked from it when the budget says so. Both numbers are here because an operator asked to see a repository at its limit — an account at its budget still serves every object, only slower, and nothing else on the dashboard would say which repositories those are.

A metadata call per pool, no store lock. Empty for an engine with no such tier.

Source

pub fn open_object_counts(self) -> Vec<(PathBuf, u64)>

Indexed objects of every open store, as (git_dir, count) — the objects meter of Usage.Read, i.e. what this process is paying RAM for (~382 B an object, measured). A closed store is absent, not zero.

Empty on the gix engine: it keeps no in-RAM object index per open store (its odb is mmapped pack indexes), so there is no per-object RAM price to report and reporting one would be a made-up bill.

Source

pub fn set_explode_budget(self, git_dir: &Path, bytes: u64) -> usize

Set the explode budget of every open repository under git_dir.

A prefix, so one call moves a whole account. Returns how many stores were changed — applied output, so a control plane that reached nothing (every repository closed) can say so instead of reporting success.

Source

pub fn hold_no_graph_memo(self)

A twin keeps no derived memo (.nornir/twin-transaction-log.md C2): the znippy engine’s persisted commit graph (objects.graph) is off for every store this process opens from now on. Process-wide, because the box’s role is — called when stores open as a twin and when a fresh box becomes one. The gix engine keeps no such file.

Source

pub fn hold_twin_memory_bound(self)

A twin holds no read cache and resolves narrow (twin-memory-bound, and lane T3’s one-medium run): the znippy engine’s explode policy is off, its explode budget is TWIN_EXPLODE_BUDGET_BYTES, and the indexer’s resolver runs TWIN_RESOLVE_WORKERS wide with TWIN_RESOLVE_LOOKAHEAD_BYTES of lookahead, for every store this process opens from now on. MEASURED: +36 MiB of RssAnon for a 512 MiB snapshot install against a 64 MiB ceiling, against +149 MiB unbounded — and, with the policy left alone, five objects.exploded files on a twin’s volume that a twin may not hold.

Process-wide, because the box’s role is. It is a SIBLING of Engine::hold_no_graph_memo and not folded into it, because the two answer different files (objects.graph against objects.exploded and the resolver’s heap) and a reader who assumed the graph door covered the cache is exactly how the twin came to hold five of them. The gix engine has neither.

Source

pub fn bound_open_stores_to_twin(self) -> u64

And the stores already open when that happened — their exploded pools unlinked and capped, since a store keeps the policy it opened with. Returns the bytes unlinked.

Source

pub fn drop_explode_cache(self, git_dir: &Path) -> u64

repo gc reclaims the read cache: every lazily-exploded object unlinked, the commit-and-tree pool kept because that is the graph. Returns the bytes that left the filesystem.

Source

pub fn ingest_push( self, git_dir: &Path, hash_kind: Kind, pack: &mut dyn BufRead, objects: ObjectSet, progress: Option<&dyn PackProgress>, before_store: Option<BeforeStore<'_>>, ) -> Result<PushReceipt>

Take one pushed packfile straight into storage, off the wire.

The bytes go from the transport into the engine and are durable when this returns. Nothing is staged through a packfile on the way: a seam spelled in paths cannot express a server without them, which is why this one is spelled in bytes.

Everything but want_objects is engine-neutral and lives in [ingest_common] — the pack header, the trailer and GitOps::put_pack are the same three facts whichever engine stored them. Enumerating the ids a push introduced is not neutral: a pack entry carries no oid, so an engine answers it out of its own index or not at all.

§progress, and why it is threaded rather than fetched

Some(sink) asks the engine to say how many objects of this pack it has taken in while it is still taking them in (GitOps::put_pack_observed). The count belongs to the code that splits the pack and to nothing else — deriving it anywhere on the way here means inflating every entry a second time, which is a second pack decoder (one implementation) — so the only thing this layer can do is carry the sink down and let the walk publish.

§before_store, and why the pushed pack is framed HERE

Called with exactly the bytes the engine is about to store, before it stores them — the transaction log’s Pack frame (gunnar_core::txlog, the twin). This path opens the engine by git_dir and never passes the OpenRepo::logged tee, so without it a pushed pack was never a frame while its ref update was: MEASURED 2026-09-15 under KVM, the twin and a restored primary both refused refs/heads/main would point at …, which this repository does not have. An error from the hook refuses the push before a byte lands.

None is not a degraded mode: a push over SSH or smart HTTP has no job record and nobody polling one, so it asks for nothing and pays for nothing. The mirror queue is the caller that has a console watching.

Source

pub fn maintain( self, git_dir: &Path, hash_kind: Kind, ) -> Result<MaintenanceReport>

gunnar gc for one repository: seal, then reclaim.

The order is the correctness argument rather than a preference. Sealing folds pending index work into the derived tables; reclaiming computes its live set out of those tables. Reclaiming first would judge liveness against a graph missing everything pushed since the last drain, and tombstone objects reachable only from those commits.

Only the znippy arm has a seal. The gix arm’s gc reads the packs and the ref store directly, so there is no pending index work for a seal to fold in, and it reports sections_sealed: 0 — which is the truth and not a stub.

Trait Implementations§

Source§

impl Clone for Engine

Source§

fn clone(&self) -> Self

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 Copy for Engine

Source§

impl Debug for Engine

Source§

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

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

impl Display for Engine

Source§

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

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

impl Eq for Engine

Source§

impl PartialEq for Engine

Source§

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

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

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

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Engine

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

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<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
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> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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