The substrate release gate (substrate/review-wave-10) verdict, landed: - OQ-21 outcome confirmed (posture evidenced; build deferral stands verbatim; OQ-03's substrate publish-side blocker stays dropped) - the substrate-side OQ-03 freeze inventory settled and reconciled against the crate root's actual re-export list (recorded for w10-publish to freeze) - the release-readiness surface verified (docs, matrix incl. the three off-matrix clippies, CHANGELOG/README, dry-run re-run; F-w10-B4/B5 + N-3 dispositions confirmed) - all flagged recorded interpretations confirmed (O-g future work, the through-store probe stamp, mem_registry removal, testutil home, LIVE_GATE stay) - the test evidence read green; review 006 R-1..R-7 verified absorbed Inline findings fixed in-session: - D-1: the architecture README's status-index cells were stale since the wave-5 flip; made truthful with the substrate.md/lfs.md `stable` flips - D-2/D-3: two task-record slips (the test-evidence Summary's O-b/O-c cross-reference; the placement task's unticked ACs) - D-4: DEFAULT_SCHEMA + LOCKED_OUT_RETRY_SECS promoted to the crate-root re-export list (both module-path-public, never root re-exported — the freeze authority byte-exact; additive pre-freeze) Verification: cargo test (376/186), --all-features 379, the live-pg harness run 212 passed 0 skips, the fuzz corpus gate 13 targets, fmt + five clippy passes (-D warnings), cargo doc 0 warnings, publish dry-run green, taskgraph validate (90 tasks).
228 lines
12 KiB
Rust
228 lines
12 KiB
Rust
//! alkgit-substrate: the shipped backend composition for the alkgit
|
||
//! protocol core.
|
||
//!
|
||
//! The complete ADR-019 composition implementing alkgit's backend seam
|
||
//! over the alkstore + alkblobs substrate — the engine-generic reactive
|
||
//! halves, the coherence-contract cached read provider, the family
|
||
//! adapter pattern with engine twins, the schema migrations, the GC
|
||
//! wiring, and the LFS surface. The spec is `docs/architecture/
|
||
//! substrate.md`; the crate/feature placement (the two-member workspace,
|
||
//! `sqlite` on / `postgres` off / `lfs` on) is ADR-025. The composition
|
||
//! consumes (identity, repo id, duplex stream, limits) and stays
|
||
//! front-door-blind: doors are family infrastructure. The traits it
|
||
//! implements and the seam types it imports —
|
||
//! [`GitRegistry`](alkgit::GitRegistry),
|
||
//! [`GitRegistryStore`](alkgit::GitRegistryStore), [`GitRefs`](alkgit::GitRefs),
|
||
//! [`GitPackGen`](alkgit::GitPackGen), [`GitPackIngest`](alkgit::GitPackIngest),
|
||
//! the [`RepoRecord`](alkgit::RepoRecord) record family — are all
|
||
//! published by the core crate; this crate re-exports none of them.
|
||
//!
|
||
//! Public API surface is the crate-root re-export list (the convention);
|
||
//! substrate.md §public API fixes the members — the exact Rust names are
|
||
//! each implementation task's to pin under OQ-03's inventory.
|
||
//!
|
||
//! # The module map (per-module, one workstream one file)
|
||
//!
|
||
//! - [`error`] — the substrate open/construction error surface
|
||
//! ([`OpenError`]): the fallible-constructor posture ADR-024 §1
|
||
//! requires (construction fails loudly; a half-migrated store refuses
|
||
//! service). Deliberately no conversion into the core's error types.
|
||
//! - [`migrations`] — the ADR-024 machinery (both engines' homes since
|
||
//! the wave-10 placement split: the co-tenant connection handles
|
||
//! [`CoTenantSqlite`] (sqlite) and [`CoTenantPg`] (postgres, whose
|
||
//! twin re-exports it) together, the migration runners, and the pg
|
||
//! SQL plumbing) + the initial co-tenant schema.
|
||
//! - [`registry`] — the registry adapter trait pair, the in-memory
|
||
//! default adapter (stamp-free per ADR-024 §6), the cached read
|
||
//! provider, the alkgit registry-pair impls, and the engine-neutral
|
||
//! [`crate::registry::HEAD_SEED_TARGET`] pin both twins seed with.
|
||
//! - [`refs`] — the refs co-tenant row table: the CAS-semantics
|
||
//! reference impl ([`InMemoryRefTable`], engine-free), the sqlite
|
||
//! row-CAS twin ([`SqliteRefTable`], the `sqlite` feature — every
|
||
//! `apply_updates` call in one `BEGIN IMMEDIATE` transaction on the
|
||
//! co-tenant `git_refs` rows) and the pg row-CAS twin
|
||
//! (`PgRefTable`, the `postgres` feature — the same one
|
||
//! transaction per call, the sqlite twin's engine-swapped, the wave-7
|
||
//! N-c rider), the table-layer name validation
|
||
//! (the core's `validate_ref_name` deny-list reused, the
|
||
//! invalid-name → `funny refname` per-ref denial mapping pinned),
|
||
//! and the unborn-HEAD symref row shape.
|
||
//! - [`reactor`] — the reactive halves: the announce composition
|
||
//! (publish/notify/enqueue, fail-soft each), the wake runner (the
|
||
//! provider's invalidation trigger), the stream consumer (the
|
||
//! cursor model + per-seq idempotency), the reconcile sweep (the
|
||
//! crash-window closure), and the engine-generic construction wiring
|
||
//! ([`Reactor`] from the engine handle + provider).
|
||
//! - `sqlite` / `postgres` — the engine twins (`sqlite` on /
|
||
//! `postgres` off per ADR-025), feature-gated module paths and so not
|
||
//! linked here: a default-feature doc build does not see them.
|
||
//! The postgres twin (`postgres`, `w6-registry-postgres`) carries
|
||
//! the LISTEN/NOTIFY-leg asymmetry (no file-level bump exists — a
|
||
//! lost hint leaves caches stale until the reconcile tick) and the
|
||
//! env-gated live-pg harness tests.
|
||
//! - [`odb`] — the object front: the alkblobs git-object-family
|
||
//! wiring ([`loose_form`], [`oid_key`], [`key_to_oid`]) and the sync
|
||
//! [`gix_object::Find`]/[`gix_object::Exists`] + [`gix_pack::Find`]
|
||
//! Find front ([`ObjectFront`] constructed once with per-session
|
||
//! [`SessionFind`] views, the miss-recording shape the
|
||
//! `StorageError::ObjectMissing` abort maps back through) with the
|
||
//! one sync/async bridge ([`ObjectFront::block_on`] from blocking
|
||
//! pipeline tasks — never from async contexts,
|
||
//! [`ObjectFront::block_in_place`] there).
|
||
//! - [`packgen`] — the substrate `GitPackGen` implement ([`PackGen`]):
|
||
//! ADR-004's pipeline over the real Find (the two-stage closure, the
|
||
//! missing-objects abort), the ADR-014 §5 ack predicate as the real
|
||
//! `common_haves`, and both serving shapes (direct streaming;
|
||
//! through-store ranged windows with mid-flight digest verification
|
||
//! over the [`PackCache`] request-digest cache), both serving straight
|
||
//! into the frozen trait's sink.
|
||
//! - [`ingest`] — the substrate `GitPackIngest` implement (`PackIngest`):
|
||
//! ADR-020 §2's ingestion composition — the budgeted host working
|
||
//! area's index (thin bases through the substrate Find), the
|
||
//! unpack-to-loose under the decompressed-size cap with the guards
|
||
//! riding the w8-pin-registry's custody seam, the full-graph
|
||
//! connectivity walk from the pushed tips, and the working-area
|
||
//! discard. Construction is the composition entry's (the working
|
||
//! area's root is the entry's config knob); the exact public names
|
||
//! join the OQ-03 substrate-side inventory with the entry task.
|
||
//! - [`compose`] — the single composition entry
|
||
//! ([`SubstrateAssembly`]): one fallible constructor per assembly
|
||
//! (mem — the completeness shape taking the substrate engine
|
||
//! handles; sqlite — the default single-host shape, config-opened
|
||
//! co-tenant; postgres — the fleet/durable-shared shape, the
|
||
//! feature), wiring the complete backend per shape: the registry
|
||
//! pair + cached read provider + reactor (the assembly shapes,
|
||
//! unified), the write-counter-wrapped refs table under the
|
||
//! w8 custody/commit side, the object front, the pack serving
|
||
//! shapes, the ingest, the registered ref-table-closure liveness
|
||
//! source, and the maintenance chain.
|
||
//! - [`liveness`] — the GC liveness source: the ref-table closure
|
||
//! ([`RefClosure`], the [`alkblobs::LivenessSource`] implement — the
|
||
//! full graph walk over the object front, parents included, gitlinks
|
||
//! neither marked nor walked), the refs-rows seam ([`RefRows`], the
|
||
//! durable refs fingerprint the memo keys on, POC-O's memoized-closure
|
||
//! shape with the invalidation mechanism pinned: read-side durable
|
||
//! fingerprint + the in-process write counter, the fleet posture
|
||
//! stated), the write-counting refs wrapper ([`VersionedRefTable`]),
|
||
//! and the registration wiring ([`RefClosure::register`]) — the
|
||
//! maintenance chain's sweep dispatch requires it.
|
||
//! - [`maintenance`] — the maintenance chain's consumer side
|
||
//! ([`MaintenanceChain`]): the `@every` sweep schedule registration
|
||
//! ([`SWEEP_SCHEDULE`]) + the supervised scheduler runner, the
|
||
//! worker's claim loop over [`MAINTENANCE_QUEUE`] (the
|
||
//! [`MaintenanceJob`]) dispatch:
|
||
//! `Sweep` → the [`MAINTENANCE_LOCK`] leader lock + the store's
|
||
//! sweep with the report as data; `PackHousekeeping` → the
|
||
//! [`PackCache`] release path), and the runner supervision (the wake
|
||
//! runner's restart on both stop shapes
|
||
//! ([`Reactor::run_wake_runner`]'s collapsed quiet returns) and the
|
||
//! reconcile tick's driving ([`MaintenanceOpts`]).
|
||
//! - [`lfs`] — the LFS pointer-lifecycle row surface (the `lfs`
|
||
//! feature; ADR-022 §4): the [`LfsRows`] trait over one row per
|
||
//! reference, the [`InMemoryLfsRows`] reference impl + the engine
|
||
//! twins ([`SqliteLfsRows`], `PgLfsRows`), the refcount semantics +
|
||
//! the re-protection contract pinned, the repo-deletion removal legs
|
||
//! riding the twins' record-removal transactions unconditionally and
|
||
//! the mem shape's legs in the composition entry, the epoch wrapper
|
||
//! ([`VersionedLfsRows`], the liveness discipline's
|
||
//! bump-after-commit half — [`crate::liveness`]) carried by the
|
||
//! twin assemblies themselves (the refs twins' posture —
|
||
//! `lfs_rows()` hands the wrapped surface, `lfs_version()` the
|
||
//! shared counter).
|
||
//! - [`lfs_adapter`] — the storage-side batch/transfer adapter (the
|
||
//! `lfs` feature; ADR-022 §1–3): the batch/checking mapping, the
|
||
//! pre-keyed put / ranged-fetch byte paths with the whole-span oid
|
||
//! verification, and the wired-provider posture ([`LfsGrantProvider`]
|
||
//! — the facade seam is the embedder's; the adapter is door-side
|
||
//! infrastructure, split documented in the module doc).
|
||
//!
|
||
//! The pending-pin registry and the receive flow's
|
||
//! committed-ref side live in the composition-internal `pins` module
|
||
//! (substrate.md §public API carries the receive-pack composition as
|
||
//! internal to the trait impls — no re-export): the
|
||
//! `PendingPinRegistry` (the pin bridge's registry half — retain from
|
||
//! prepare, drain-with-correlation from apply, prune-stale from any
|
||
//! apply, drop-on-abort), the `CommittedRefs` wrapped `GitRefs`
|
||
//! implement (stale-prune → CAS → drain-only-after-commit, then the
|
||
//! post-CAS marker + announce legs fail-soft), and the
|
||
//! `RegistryMutations` legs surface (the mem shape's fused legs plus
|
||
//! the engine-twin assemblies' impls).
|
||
//!
|
||
//! # The composition entry's pinned decisions (OQ-03 inventory,
|
||
//! `compose`)
|
||
//!
|
||
//! `SubstrateAssembly` (`mem`/`sqlite`/`postgres` + accessors),
|
||
//! `AssemblyOptions`, `PackServing` — the re-export list grows by
|
||
//! exactly the entry surface.
|
||
|
||
#![forbid(unsafe_code)]
|
||
|
||
pub mod compose;
|
||
pub mod error;
|
||
pub mod ingest;
|
||
#[cfg(feature = "lfs")]
|
||
pub mod lfs;
|
||
#[cfg(feature = "lfs")]
|
||
pub mod lfs_adapter;
|
||
pub mod liveness;
|
||
pub mod maintenance;
|
||
pub mod migrations;
|
||
pub mod odb;
|
||
pub mod packgen;
|
||
mod pins;
|
||
#[cfg(feature = "postgres")]
|
||
pub mod postgres;
|
||
pub mod reactor;
|
||
pub mod refs;
|
||
pub mod registry;
|
||
#[cfg(feature = "sqlite")]
|
||
pub mod sqlite;
|
||
|
||
/// The test-only harness helper home (review 006 R-3) — compiled only
|
||
/// under test, never public API surface.
|
||
#[cfg(test)]
|
||
pub(crate) mod testutil;
|
||
|
||
pub use compose::{AssemblyOptions, PackServing, SubstrateAssembly};
|
||
pub use error::OpenError;
|
||
#[cfg(all(feature = "lfs", feature = "postgres"))]
|
||
pub use lfs::PgLfsRows;
|
||
#[cfg(all(feature = "lfs", feature = "sqlite"))]
|
||
pub use lfs::SqliteLfsRows;
|
||
#[cfg(feature = "lfs")]
|
||
pub use lfs::{InMemoryLfsRows, LfsRow, LfsRows, VersionedLfsRows};
|
||
#[cfg(feature = "lfs")]
|
||
pub use lfs_adapter::{
|
||
LfsActions, LfsAdapter, LfsAdapterConfig, LfsAdapterError, LfsBatchObject, LfsBatchOperation,
|
||
LfsBatchRequest, LfsBatchResponse, LfsDownload, LfsGrantProvider, LfsHrefMint, LfsObjectAnswer,
|
||
LfsObjectError, LfsRange,
|
||
};
|
||
#[cfg(feature = "lfs")]
|
||
pub use liveness::{lfs_media_key, LfsMedia};
|
||
pub use liveness::{RefClosure, RefRow, RefRowState, RefRows, RefRowsSnapshot};
|
||
pub use maintenance::{
|
||
MaintenanceChain, MaintenanceOpts, SweepVerdict, WorkerEvent, LOCKED_OUT_RETRY_SECS,
|
||
SWEEP_SCHEDULE,
|
||
};
|
||
#[cfg(feature = "sqlite")]
|
||
pub use migrations::CoTenantSqlite;
|
||
pub use odb::{key_to_oid, loose_form, oid_key, ObjectFront, SessionFind};
|
||
pub use packgen::{PackCache, PackGen};
|
||
#[cfg(feature = "postgres")]
|
||
pub use postgres::{CoTenantPg, PgRegistry, PgRegistryAssembly, PgRegistryOptions, DEFAULT_SCHEMA};
|
||
pub use reactor::{
|
||
AnnounceReport, AnnouncingRegistry, AppliedWatermark, MaintenanceJob, Reactor, RegistryEvent,
|
||
EVENTS_STREAM, MAINTENANCE_LOCK, MAINTENANCE_QUEUE, WAKE_CHANNEL,
|
||
};
|
||
#[cfg(feature = "postgres")]
|
||
pub use refs::PgRefTable;
|
||
#[cfg(feature = "sqlite")]
|
||
pub use refs::SqliteRefTable;
|
||
pub use refs::{InMemoryRefTable, VersionedRefTable, CAS_STALE_REASON};
|
||
pub use registry::{
|
||
CachedRegistryProvider, InMemoryRegistry, RegistryBackend, RegistryRead, RegistryRow,
|
||
RegistryWrite, HEAD_SEED_TARGET,
|
||
};
|
||
#[cfg(feature = "sqlite")]
|
||
pub use sqlite::{SqliteRegistry, SqliteRegistryAssembly};
|