| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Ecluse.Core.Registry.Metadata
Description
The serve-path metadata handle: the read boundary between the request pipeline and a registry mount, expressed as two implementation-agnostic intent operations.
This is the read counterpart to the publish-side Ecluse.Core.Registry handle, and deliberately distinct from it. The publish handle is the write/worker side (one client minted once at the composition root); this handle is the serve path's read boundary, constructed per request so it can capture the per-origin manager, credential posture, base URL, and response budget -- and the shared metadata cache -- that a serve fetch needs. The pipeline never reaches for a registry's wire format: it asks a mount for one of two things and the mount owns both fetch and parse behind the answer.
The two operations are asymmetric by design:
fetchFullManifestyields the packument-levelPackageInfoand the raw document it was decoded from. The serve path needs the raw document because it edits the packument in place (dropping filtered versions, rewriting artifact locations) and re-serializes it to the client -- andPackageInfois a lossy projection that cannot reconstruct the document.fetchVersionMetadatayields only one version'sPackageDetails. It never re-serializes, so it need not carry the raw document -- which is what lets a mount make it the cheap path (a smaller endpoint, or a selective parse) without changing this boundary.
Both operations are total: a failure is reported as a MetadataError value, not
thrown, so the caller decides how each maps onto a served response. A genuine
transport fault (an unreachable upstream) is the exception channel the caller already
brackets; this Either is the parse and policy channel.
Synopsis
- data MetadataClient = MetadataClient {}
- data Manifest = Manifest {}
- data ContentDigest
- digestOf :: ByteString -> ContentDigest
- digestBytes :: ContentDigest -> ByteString
- data MetadataError
- data VersionEvaluation
- fetchVersionDetails :: MetadataClient -> PackageName -> Version -> IO VersionEvaluation
The read handle
data MetadataClient Source #
The serve-path read handle -- a record of two intent operations over a registry
mount, whose private state (the per-origin fetch configuration and the shared cache)
the closures capture. Both fields return IO so a backend stays decoupled from the
proxy core, exactly as the publish-side handle does.
Constructors
| MetadataClient | |
Fields
| |
The full-manifest result
A resolved full manifest: the typed packument-level view, the raw document it was
decoded from (the serve path edits and re-serialises it), and the ContentDigest of
the wire bytes both were derived from -- the input fingerprint the serve path's
derived ETag is built over (Conditional).
Constructors
| Manifest | |
Fields
| |
data ContentDigest Source #
A SHA-256 digest of one origin's wire body -- the exact bytes a manifest was
decoded from, hashed once at the read boundary (where the strict body already exists)
so downstream consumers can fingerprint a document without re-encoding or re-hashing
it. Opaque: built only by digestOf, read only by digestBytes.
Instances
| Show ContentDigest Source # | |
Defined in Ecluse.Core.Registry.Metadata Methods showsPrec :: Int -> ContentDigest -> ShowS # show :: ContentDigest -> String # showList :: [ContentDigest] -> ShowS # | |
| Eq ContentDigest Source # | |
Defined in Ecluse.Core.Registry.Metadata Methods (==) :: ContentDigest -> ContentDigest -> Bool # (/=) :: ContentDigest -> ContentDigest -> Bool # | |
digestOf :: ByteString -> ContentDigest Source #
Digest a strict body -- one O(body) pass, paid at fetch time, never per serve.
digestBytes :: ContentDigest -> ByteString Source #
The digest's raw 32 bytes, for feeding into a wider fingerprint.
Errors
data MetadataError Source #
Why a metadata fetch could not yield a usable result -- reported as a value so the serve path maps each cause onto the response it renders, byte-for-byte as before.
Each constructor preserves a distinction the serve path acts on: a name mismatch is held apart from a plain decode failure because a mount answering for a different package is an untrusted, misreporting origin (the anti-shadowing defence), dropped and surfaced distinctly rather than degraded like an outage.
Constructors
| MetadataBoundExceeded LimitError | The upstream body breached a response bound (its size, version count, or
nesting depth). Carries the |
| MetadataUndecodable | The upstream answered, but its body did not decode into a usable manifest (malformed JSON, or an absent/undecodable top-level name). |
| MetadataNameMismatch Text | The upstream answered with a manifest that self-reported a different package's name (carried verbatim for the audit log). The origin is untrusted for this request and dropped -- never served as the requested package. |
Instances
| Show MetadataError Source # | |
Defined in Ecluse.Core.Registry.Metadata Methods showsPrec :: Int -> MetadataError -> ShowS # show :: MetadataError -> String # showList :: [MetadataError] -> ShowS # | |
| Eq MetadataError Source # | |
Defined in Ecluse.Core.Registry.Metadata Methods (==) :: MetadataError -> MetadataError -> Bool # (/=) :: MetadataError -> MetadataError -> Bool # | |
Single-version resolution
data VersionEvaluation Source #
The outcome of resolving one version's metadata for a policy decision: the projected version snapshot when present, or the degrade both the serve-time gate and the mirror worker map onto their own response. It is the shared classification of a single-version fetch, so the gate that decides what to serve and the worker that decides what to mirror reach the same three outcomes from the same fetch and projection.
Constructors
| VersionPresent PackageDetails | The version resolved and projected; its |
| VersionMissing | The package resolved but does not carry the requested version (a withdrawn or never-published version), a genuine absence distinct from unobtainable metadata. |
| VersionMetadataUnavailable | The metadata could not be obtained at all: a transport fault, or any
|
Instances
| Show VersionEvaluation Source # | |
Defined in Ecluse.Core.Registry.Metadata Methods showsPrec :: Int -> VersionEvaluation -> ShowS # show :: VersionEvaluation -> String # showList :: [VersionEvaluation] -> ShowS # | |
| Eq VersionEvaluation Source # | |
Defined in Ecluse.Core.Registry.Metadata Methods (==) :: VersionEvaluation -> VersionEvaluation -> Bool # (/=) :: VersionEvaluation -> VersionEvaluation -> Bool # | |
fetchVersionDetails :: MetadataClient -> PackageName -> Version -> IO VersionEvaluation Source #
Resolve a single version's metadata through a MetadataClient and classify the
outcome into a VersionEvaluation: the one fetch-and-project step both the serve-time
tarball gate and the mirror worker run before the rules engine, so a future rule that
reads a new field sees the same projected PackageDetails in either context.
A transport fault (the exception channel the client leaves to its caller) and any
MetadataError alike classify as VersionMetadataUnavailable, collapsing every
unobtainable-metadata cause to the one transient outcome; a resolved-but-absent version is
VersionMissing; a resolved version is VersionPresent. Total: a fetch failure becomes a
classified value, never an escaping exception.