Skip to content

Tokens and cache keys

Every cache the library keys derives from the edition's token, and so does the ETag. A new edition has a new token, so nothing keyed on the old one is served again, and no cache needs an invalidation path. The ETag also hashes the app version, so a release of the service changes every ETag too.

The token

CatalogRuntime.token is the provider's OpenedCatalog.token when it is set. OpenedCatalog.token defaults to "", and the runtime then uses the edition manifest's edition_id, the edition's directory name, or build_id when the registry has no manifest (runtime.py).

The effective token

A MessageAnnotator can change a response without a new edition, for example when a deployment replaces an annotation overlay. Keyed on the token alone, the structure cache would keep serving the old body, and a client sending If-None-Match would get a 304 for it (GitLab #12).

An annotator whose output can change implements SupportsFingerprint. The runtime folds the fingerprint into the token:

effective_token = sha256("v3\n" + token + "\n" + fingerprint)

An empty fingerprint leaves effective_token equal to token, so a service with no annotator keeps the ETags it had. The first line, v3, follows sdmxlib's effective_token, which moved from v2 to v3 with manifest 3.0 (sdmxlib 0.80). When the provider sets no token and an OverlayAnnotator is the only annotator, the hashed text matches sdmxlib's effective_token, so a tool that computes the token from a manifest and its overlays with sdmxlib predicts the service's ETag. A CompositeMessageAnnotator prefixes each member's fingerprint with its position, and the two tokens then differ.

The runtime reads the fingerprint on every request, so a fingerprint is a stored value or a counter and does no I/O.

What keys on which

Key Token Why
ETag effective_token An annotation change changes the body
StructureQuery.token effective_token The cached body includes annotations
SpliceContext.token effective_token A splice that caches sees the annotated body
AvailabilityKey.token token Annotations cannot change which values occur
annotate(token=) token An annotator memoises per edition

The ETag hashes the app version, the effective token, the path, the query string, Accept and the resolved language. It never reads the body, so it is computed before the route runs and is identical with or without compression.

Last-Modified has its own source. With a fingerprint it is the later of the edition's time and the moment this process first saw the fingerprint, so a restart moves Last-Modified while the ETag holds.

Open proposal

GH-10 proposes keying the caches and ETags on a content token, so that a new edition whose content did not change keeps its ETags, and shipping a baker and pluggable cache backends. It would change the first section of this page.