Documentation
¶
Index ¶
- Constants
- Variables
- func CacheableStatus(code int) bool
- func DeclaredTag(subgraph, tag string) string
- func EncodeItem(item Item) ([]byte, error)
- func Key(entity, selection Digest) string
- func MergeVarySets(own []string, seen [][]string) [][]string
- func PrivateKey(entity, selection, privateID Digest) string
- func SortSurrogateKeys(surrogateKeys []SurrogateKey)
- func SubgraphTag(subgraph string) string
- func SurrogateKeyValues(surrogateKeys []SurrogateKey) []string
- func TypeTag(subgraph, typeName string) string
- func ValidDeclaredSurrogateKey(tag string) bool
- func VariantKey(base string, vary Digest) string
- func Vary(headers http.Header) (names []string, star bool)
- type Cache
- type CachePolicy
- type Digest
- type Item
- type SetManyError
- type StoreDecision
- type SurrogateKey
- func DeclaredSurrogateKey(tag string) SurrogateKey
- func DecodeEntry(b []byte) (value []byte, surrogateKeys []SurrogateKey, vary [][]string, err error)
- func MergeSurrogateKeys(dst []SurrogateKey, src ...[]SurrogateKey) []SurrogateKey
- func SubgraphSurrogateKey(subgraph string) SurrogateKey
- func TypeSurrogateKey(subgraph, typeName string) SurrogateKey
- type SurrogateKeyTier
Constants ¶
const MaxVaryHeaders = 100
MaxVaryHeaders bounds a vary record. A response naming more is not stored.
const MaxVarySets = 8
MaxVarySets bounds the name sets a record keeps. Past it the oldest go.
Variables ¶
var ( ErrMissingTTL = errors.New("cache item requires a positive TTL") ErrNoKeys = errors.New("response cache lookup requires at least one key") ErrNoItems = errors.New("response cache write requires at least one item") ErrInvalidSurrogateKeyTier = errors.New("surrogate key has an unknown tier") )
var ErrEntryFormat = errors.New("cache entry is not in a known format")
Functions ¶
func CacheableStatus ¶ added in v2.31.0
CacheableStatus reports whether a response with this status may be stored: 200 or 203, or 0 from a data source without HTTP. A cache without Range or validation must not store 206 or 304 (RFC 9111 §3).
func DeclaredTag ¶ added in v2.20.0
A subgraph name carrying the separator would otherwise spell another subgraph's tag, so separators within the scope are doubled and the single one after it is what ends the scope.
func EncodeItem ¶ added in v2.24.0
EncodeItem picks the envelope the item calls for. Empty vary sets are dropped, since a set names at least one header and DecodeEntry refuses a record that says otherwise; with no set left the item is a body. A key with an unknown tier is refused, as DecodeEntry would refuse the entry.
func MergeVarySets ¶ added in v2.24.0
MergeVarySets is the record to write after a response varying on own: own first, then every set the record held before, so the variants stored under them stay reachable. Names come sorted and deduplicated from Vary, so equal sets are equal slices.
func PrivateKey ¶ added in v2.22.0
PrivateKey builds the key for one entity within one fetch as seen by one user.
func SortSurrogateKeys ¶ added in v2.22.0
func SortSurrogateKeys(surrogateKeys []SurrogateKey)
SortSurrogateKeys groups by tier, coarsest first, keeping the order within a tier.
func SubgraphTag ¶ added in v2.20.0
func SurrogateKeyValues ¶ added in v2.30.1
func SurrogateKeyValues(surrogateKeys []SurrogateKey) []string
SurrogateKeyValues is the distinct values, first seen order, tiers dropped.
func ValidDeclaredSurrogateKey ¶ added in v2.22.0
ValidDeclaredSurrogateKey reports whether a declared tag can go in a header. One spelled like a derived key passes: the header is the CDN's contract and carries what the subgraph declared, the index files it as declared.
func VariantKey ¶ added in v2.24.0
VariantKey builds the key of one variant of the entry at base, a public or private key, for the request header values vary digests.
Types ¶
type Cache ¶
type Cache interface {
// GetMany looks up every key and returns the ones it found, keyed by the
// key they were asked for, with the SurrogateKeys they were stored with. A
// miss is simply absent, never an error and never a zero Item.
GetMany(ctx context.Context, keys []string) (map[string]Item, error)
// SetMany stores every item, all of which must carry a positive TTL. When
// items contains the same key twice, the last one wins. An error means an
// unspecified subset of the items may already have been stored.
// In case any of the passed ttls are invalid, SetMany should return
// without saving any items that may have valid ttl values.
SetMany(ctx context.Context, items []Item) error
}
Cache is a batch oriented key/value cache.
type CachePolicy ¶ added in v2.31.0
type CachePolicy struct {
Decision StoreDecision
// TTL is how long the router may keep it: s-maxage, else max-age, else
// Expires, else the fallback, net of Age.
TTL time.Duration
// ClientTTL is how long a client may keep it: max-age, else Expires, net
// of Age, never over TTL. Zero when SharedOnly.
ClientTTL time.Duration
// or public on the fallback. Clients get no lifetime from it. Without
// public a fallback lifetime stays a max-age, as s-maxage would grant
// sharing.
SharedOnly bool
// Public is the response's own public directive.
Public bool
// Private is stored per user only: private, or a request with
// Authorization the response did not allow to be shared.
Private bool
}
CachePolicy is what a response allows the cache and the client. Decision is StoreDecisionStored, or why it is not stored; the rest is zero then.
func CachePolicyOf ¶ added in v2.31.0
func CachePolicyOf(headers, sent http.Header, defaultTTL time.Duration) CachePolicy
CachePolicyOf reads what a response allows the cache and the client. sent is the request the subgraph answered: one carrying Authorization is only shared when the response allows it (RFC 9111 §3.5), and is otherwise private.
type Digest ¶ added in v2.22.0
Digest is the SHA-256 of one input to a key. Collision resistant, so two inputs cannot end up on one key, and fixed size, so raw inputs never reach the store.
func DigestBytes ¶ added in v2.22.0
func DigestParts ¶ added in v2.22.0
DigestParts digests the parts in order, each led by its length, so no byte can move between parts unnoticed, whatever the parts contain.
func DigestString ¶ added in v2.22.0
type Item ¶
type Item struct {
// Key is the key the entry is stored under, exactly as GetMany was asked
// for it, so an Item carries enough to be acted on once it has been taken
// out of the map it came in.
Key string
// Value is the cached bytes. An entry with an empty Value is still an
// entry: GetMany omitting the key is the only thing that means a miss.
Value []byte
// TTL is how long the entry should live when passed to SetMany, and how
// much of that life it has left when returned by GetMany, so the same key
// comes back with less of it on every lookup. It is always positive in
// both directions: SetMany refuses an item without a positive TTL, and
// GetMany treats an entry with nothing left to live, or one it finds with
// no expiry attached at all, as a miss rather than a hit.
TTL time.Duration
// Tags are the cache tags the entry was stored under, a secondary index
// naming what the entry is about so it can later be found by something other
// than its key for invalidation.
Tags []string
// Surrogate keys are what a client response carries so a CDN can purge by them.
// Stored with the value and returned by GetMany.
SurrogateKeys []SurrogateKey
// Vary makes the entry a vary record rather than a body: the sets of
// request headers responses at this key have varied on, newest first.
// Each set's values select a variant stored under VariantKey. A record has
// no Value and no SurrogateKeys.
Vary [][]string
// Public is whether the response said public, so a hit says it only then.
Public bool
// its own. Stored and returned with the value.
SharedOnly bool
// ClientTTL is CachePolicy.ClientTTL: how long a client may keep the
// entry, never over TTL. Like TTL, GetMany returns what is left of it.
ClientTTL time.Duration
// FetchedAt is when the fetch behind the item started. A store drops the
// item if one of its tags was invalidated since. Not stored.
FetchedAt time.Time
}
Item is a single cache entry, both on the way in through SetMany and on the way back out of GetMany.
type SetManyError ¶
type SetManyError struct {
// This depicts the known stored keys in a case of a partial write
// this means that some more keys could have been written but there is no way to know
// because the client did not receive a response
KnownStoredKeys []string
Err error
}
func (*SetManyError) Error ¶
func (e *SetManyError) Error() string
func (*SetManyError) Unwrap ¶
func (e *SetManyError) Unwrap() error
type StoreDecision ¶ added in v2.28.0
type StoreDecision uint8
StoreDecision is what became of a response on its way into the cache. Order matters: lower wins when merged. Insert new values in check order.
const ( // StoreDecisionNone is a response nothing was decided for: the fetch was // answered from the cache, or is not cached at all. StoreDecisionNone StoreDecision = iota // none StoreDecisionStored // stored StoreDecisionFetchFailed // fetch_failed StoreDecisionUncacheableStatus // uncacheable_status StoreDecisionResponseErrors // response_errors StoreDecisionInvalidResponse // invalid_response StoreDecisionInvalidCacheControl // invalid_cache_control StoreDecisionNoStore // no_store StoreDecisionNoCache // no_cache StoreDecisionNoDirective // no_directive StoreDecisionNoLifetime // no_lifetime StoreDecisionUnusableVary // unusable_vary StoreDecisionPrivateWithoutID // private_without_id StoreDecisionNoEntity // no_entity )
func (StoreDecision) String ¶ added in v2.28.0
func (i StoreDecision) String() string
type SurrogateKey ¶ added in v2.30.1
type SurrogateKey struct {
Value string
Tier SurrogateKeyTier
}
SurrogateKey is what a client response carries so a CDN can purge by it. The tier is kept beside the value: a declared tag may be spelled like a derived one.
func DeclaredSurrogateKey ¶ added in v2.30.1
func DeclaredSurrogateKey(tag string) SurrogateKey
func DecodeEntry ¶ added in v2.22.0
func DecodeEntry(b []byte) (value []byte, surrogateKeys []SurrogateKey, vary [][]string, err error)
DecodeEntry is DecodeItem without the client directives.
func MergeSurrogateKeys ¶ added in v2.22.0
func MergeSurrogateKeys(dst []SurrogateKey, src ...[]SurrogateKey) []SurrogateKey
MergeSurrogateKeys appends every key of src not already in dst, first seen order. Equal values of different tiers are both kept.
func SubgraphSurrogateKey ¶ added in v2.22.0
func SubgraphSurrogateKey(subgraph string) SurrogateKey
func TypeSurrogateKey ¶ added in v2.22.0
func TypeSurrogateKey(subgraph, typeName string) SurrogateKey
type SurrogateKeyTier ¶ added in v2.30.1
type SurrogateKeyTier uint8
SurrogateKeyTier is where a surrogate key came from. Coarsest first, so a size limit cuts the finest purge surface.
const ( // SurrogateKeyTierSubgraph names the subgraph that answered. SurrogateKeyTierSubgraph SurrogateKeyTier = iota // SurrogateKeyTierType names an entity type of that subgraph. SurrogateKeyTierType // SurrogateKeyTierDeclared is a tag the subgraph declared, verbatim. SurrogateKeyTierDeclared )