Skip to main content

Module storage

Module storage 

Source
Expand description

The znippy cold tier, wired where objects enter the server. Which storage engine this binary carries, and which one it is running.

There is one storage contract in the constellation and it is git_storage_trait::GitOps — the eleven — which lives in znippy beside its main implementation. This module is the only place in gunnar that names an implementation of it.

                  git-storage-trait :: GitOps
                   ┌───────────┴───────────┐
       znippy-plugin-git            storage-git-gix
       (Arrow-IPC archive)          (gix-odb / gix-ref)
           `engine-znippy`              `engine-gix`
                   └───────────┬───────────┘
                           Engine::open_repo
                       ──▶ Arc<OpenRepo>

§What used to be here, and why it is gone

A second, older seam: trait StorageEngine with install(), installed() and a static ENGINE: OnceLock<&'static dyn StorageEngine>. It existed because the engine was chosen by linking a different crate — gunnar-znippy — which had to run install() before run(), and therefore needed a main of its own. That crate declared [[bin]] gunnar and [[bin]] gunnar-server, two names the build declaration had already assigned to gunnar-cli and to this package, while being absent from that declaration itself: an undeclared second writer of two declared artifact names. It is why every matrix-built binary answered “this binary carries no storage engine”.

The engine is a feature now. There is nothing left to install, so there is no OnceLock, no install, and no engine-free build — see the compile_error! below. gunnar-znippy is deleted.

§Both engines may be compiled in at once

Cargo features are additive and must be, so this is the correct idiom rather than a compromise:

buildengines linkedselection
--features engine-znippy,engine-gixbothruntime, GUNNAR_ENGINE, defaulting to znippy
defaultznippy onlynothing to select
--no-default-features --features server,engine-gixgix onlynothing to select

The rule. When both are compiled the default is znippy, and asking for an engine that was not compiled in fails loudly, at startup, before anything is served. It never silently falls back to the other: a server quietly serving from the wrong engine is the worst possible outcome of this seam, and it is the one failure a measurement cannot see.

That rule is kept by construction rather than by a check. Engine’s variants are themselves #[cfg]-gated, so in a gix-only build the value Engine::Znippy does not exist and cannot be constructed by any path, mistaken or otherwise. Engine::from_name still knows the name, which is what lets it refuse with “this binary was built without it” rather than with “unknown engine”.

§znippy’s build-time C toolchain, and why this module is where the cost lands

Cargo reads a path dependency’s manifest at resolve time whether or not the feature selecting it is on. Naming znippy-plugin-git here therefore makes a sibling znippy checkout a hard requirement of every build of this workspace. MEASURED 2026-08-10 — see this crate’s Cargo.toml, which records the command, the output and the 30 packages it adds to Cargo.lock.

Modules§

encrypted_quarantine
An encrypted repository’s push, checked before a byte of it is kept (crypt-level2 item 4; crate::encrypted_quarantine re-exports it). Here, not beside transport.rs, because it walks the pushed pack with the znippy engine’s own reader — and the engine is named in this seam and nowhere else. An encrypted repository’s push, checked in quarantine (2026-10-06, crypt-level2 item 4 pulled forward).
writer
Which writer arm this process appends through, decided once, said once.
znippy_engine
The engine seam. znippy_plugin_git:: may be named here and nowhere else — xtask’s Rule::EngineByName says so, because this file’s own header claims to be the only place in gunnar that names an implementation.

Structs§

ExplodeBand
One repository’s exploded read cache: what it holds, what it may hold, and what has already been evicted from it. Engine-neutral by construction — znippy_plugin_git::exploded_cache::CacheUse copied field for field, so a dashboard cell cannot tell which engine answered.
IndexSnapshot
One repository, opened on whichever engine this process carries.
MaintenanceReport
What one maintenance run did. Applied outputs, read off the result.
OpenRepo
one authority because GitServe is GitOps.
PushReceipt
What one push stored, read back off what was written.

Enums§

Engine
A storage engine this binary actually carries.
ObjectSet
How badly the caller needs the object set a push introduced.

Constants§

DEFAULT_ENGINE
The engine a build carrying znippy runs unless told otherwise.
ENGINE_ENV
The environment variable that picks an engine in a build carrying both.
NORDISK_REPOS
Where the nordisk repositories live — the ONE place an engine’s source URL is spelled: the nordisk organisation on git.gunnar.rs, the repositories’ home. A link only (Admin.StorageInfo’s repo_url); nothing clones it.
TWIN_EXPLODE_BUDGET_BYTES
16 MiB explode budget on a twin (same measurement). With the policy off nothing is stored at all; the cap is what keeps a later policy change bounded.
TWIN_RESOLVE_LOOKAHEAD_BYTES
16 MiB of resolver lookahead on a twin (same measurement) — the bytes the workers may run ahead of the ordered output by. znippy’s own default is 32 MiB.
TWIN_RESOLVE_WORKERS
Two resolver workers on a twin. MEASURED 2026-09-15 (tests/twin_snapshot_memory.rs): one worker per core, each inflating a whole blob, grew RssAnon +133 MiB for a 512 MiB snapshot install even with explode and graph off. Handed to znippy_plugin_git::set_resolve_workers_default by Engine::hold_twin_memory_bound.

Functions§

shutdown
Release every store this process cached, on the way out.
writer_arm
The writer arm the znippy engine built its stores on (uring / safe), for the dashboard’s disk cell; None before the first store, or on an engine that has no arms.

Type Aliases§

BeforeStore
The hook Engine::ingest_push runs on the pack before a byte of it is stored; an error refuses the push.