Skip to content

Replace custom HTTP cache policy with http-cache-semantics across memory and persistent caches #229

Description

@ctoth

Problem and decision

Adopt http-cache-semantics for HTTP cache policy and remove the custom policy implementation in src/cache.ts. Cacophony currently writes no-store responses to persistent storage and returns decoded memory entries without checking freshness or storage policy. A replacement confined to header parsing would leave those failures intact.

Evaluated at Cacophony 665b33251d5c9597943c77a9d71dd2e81a2c92a6. A public AudioCache.getAudioBuffer() reproduction with real Fetch Response objects, an in-memory Cache API and fake decoder made one fetch for two sequential no-store requests, and stored both body and metadata. Source locations: src/cache.ts:497, :840, :913; custom parsing at :115 and :133. Expired explicit max-age without validators can also fall through to the default TTL.

Upstream selection

  • BSD-2-Clause is approved for this use; retain the complete copyright/license/disclaimer in distributed artifacts.
  • Evaluated 4.1.1 passes no-store, Vary mismatch, fresh must-revalidate, and serialized-policy roundtrip fixtures.
  • Do not blindly adopt 4.2.0: it revalidates fresh max-age=3600, must-revalidate entries. Reproduced locally and tracked by upstream PR #54. Use the evaluated release or a released fix that passes these fixtures. Do not fork or patch around upstream policy internals.
  • Upstream API; use version-appropriate public CachePolicy methods, including storage/reuse decisions, conditional request headers, revalidated policy, and serialization.

Implementation scope

  • Make a policy associated with each HTTP representation authoritative before reuse in both decoded memory and persistent caches, including the Cache-API-absent Node path. A no-store response may satisfy its current request but must not be retained for subsequent reuse.
  • Remove parseMaxAge, requiresRevalidation, and the bespoke timestamp-based HTTP decision tree once replaced. Retain Cacophony's storage, decoding, byte-bounded LRU, context isolation, progress callbacks, and cancellation/dedup machinery.
  • Persist enough response/request policy data for revalidation and Vary matching; normalize header names and distinguish cache variants. Use private/single-user policy where the cache belongs to a single user. Do not pretend unavailable browser-managed request headers are known; choose conservative reuse when a Vary dimension cannot be established.
  • Merge policy after 304 responses, invalidate/replace decoded content when representation changes, and retain the unconditional retry for a 304 with a missing cached body. A pair of body/policy writes must recover safely from partial failure.
  • Version metadata. Treat old entries without usable policy as misses/revalidation candidates; do not trust legacy TTL metadata as policy.
  • Define the existing configurable fallback TTL only for genuinely unspecified freshness, without overriding explicit server directives. Preserve data-URL behavior outside HTTP policy.

Acceptance criteria

  • Regression tests through getAudioBuffer() cover sequential no-store requests (no decoded/persistent retention), no-cache revalidation, explicit max-age expiry without validators, Age-adjusted freshness, fresh and stale must-revalidate, Vary mismatch and Vary: *, and private-cache behavior.
  • Test 304 policy/header updates, changed validators/200 replacement, missing-body retry, policy serialization, legacy metadata, and unavailable Cache API. Check HTTP policy is not bypassed by a memory hit.
  • Existing independent-caller abort, pending-request sharing, per-context decoding, callbacks, data URLs, and cache byte limits still pass.
  • Test browser-visible Fetch/Cache behavior as well as pure policy fixtures. Include a CORS/header-visibility case relevant to Vary or validators.
  • Measure actual consumer bundle impact and pass package/type/browser/Node checks for supported runtimes. Publish notices. No local policy fork or second decision tree remains.

Evaluation limits

The evaluation proved current cache failures and candidate policy behavior; it did not implement or benchmark the full cache integration. Browser HTTP caching and audio decoding were not part of the reproduction. This issue is the implementation scope and validation contract.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions