cache

package
v0.27.92 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: Apache-2.0, MIT Imports: 23 Imported by: 0

Documentation

Overview

Package cache implements a caching family of filters.

Index

Constants

View Source
const (
	Name = filters.CacheName
)

Variables

This section is empty.

Functions

func NewCacheFilter

func NewCacheFilter(opts Options) filters.Spec

NewCacheFilter returns a Spec for the cache() filter.

Route usage (RFC mode — upstream Cache-Control is fully authoritative):

-> cache() -> "https://example.org"

Route usage (force mode — operator TTL is authoritative, upstream directives ignored):

-> cache("5m", "15s", "30s") -> "https://example.org"

Combining force mode with stale-if-error:

-> cache("5m", "15s", "30s", "60s") -> "https://example.org"

Types

type Entry

type Entry struct {
	// StatusCode is the HTTP status code of the cached response.
	StatusCode int
	// Payload is the serialised response body.
	Payload []byte
	// Header contains the response headers as stored at cache time.
	Header http.Header
	// CreatedAt is the wall-clock time at which this entry was stored.
	CreatedAt time.Time
	// TTL is the freshness lifetime of the entry.
	TTL time.Duration
	// StaleWhileRevalidate is the window after TTL expiry during which a stale
	// response may be served while a background revalidation is in flight.
	StaleWhileRevalidate time.Duration
	// ETag is the entity tag from the upstream response, used for conditional
	// revalidation (If-None-Match).
	ETag string
	// LastModified is the Last-Modified value from the upstream response, used
	// for conditional revalidation (If-Modified-Since).
	LastModified string
	// VaryHeaders lists the request header names captured from the original
	// request that were used to derive the cache key, matching the upstream
	// Vary response header.
	VaryHeaders []string
	// CorrectedInitialAge is the age correction term defined in RFC 9111 §4.2.3.
	// When zero, setAgeHeader falls back to the legacy elapsed-time formula.
	CorrectedInitialAge time.Duration
	// ResponseTime is the local time at which the upstream response was received,
	// used together with CorrectedInitialAge for RFC 9111 §4.2.3 age calculation.
	ResponseTime time.Time
	// StaleIfError extends the hard-expiry retention window so the entry remains
	// retrievable during upstream error periods (RFC 5861 stale-if-error).
	StaleIfError time.Duration
}

Entry holds a cached HTTP response and the metadata required for freshness evaluation, conditional revalidation, and Age header calculation.

func (*Entry) IsStale

func (e *Entry) IsStale(now time.Time) bool

IsStale reports whether the entry is past its TTL but still within the stale-while-revalidate window relative to now.

func (*Entry) IsUsable added in v0.27.85

func (e *Entry) IsUsable(now time.Time) bool

IsUsable reports whether the entry is fresh or within the stale-while-revalidate window. Entries past TTL+SWR are retained only for stale-if-error and must not be served.

type L2Client added in v0.27.85

type L2Client interface {
	Get(ctx context.Context, key string) (string, error)
	SetWithExpire(ctx context.Context, key string, value string, expire time.Duration) error
	Del(ctx context.Context, key string) (int64, error)
}

L2Client provides the key-value operations required by L2Storage.

type L2Storage added in v0.27.85

type L2Storage struct {
	// contains filtered or unexported fields
}

L2Storage implements Storage using a L2Client with write-through warming of LRUStorage (L1). On L2Client Set errors, L1 is used as a fallback. On L2Client Get errors, the request is treated as a miss and fetched from origin.

func NewL2Storage added in v0.27.85

func NewL2Storage(l2client L2Client, l1 *LRUStorage, m metrics.Metrics, l1TTL time.Duration, isNoErr func(error) bool) *L2Storage

NewL2Storage creates a *L2Storage backed by ring (L2) with l1 as the fallback in-memory cache. m is used to record per-operation counters:

  • l1_hit — L1 returned a warm entry; L2 not consulted
  • l2_miss — clean cache miss (key not found in L2)
  • l2_get_error — L2 error on Get; treated as a cache miss
  • l2_set_fallback — L2 error on Set; entry written to L1 only
  • l2_hit — successful L2 Get (entry returned from L2)

Pass metrics.Default when no test-scoped metrics collector is needed.

func (*L2Storage) Delete added in v0.27.85

func (s *L2Storage) Delete(ctx context.Context, key string) error

func (*L2Storage) Get added in v0.27.85

func (s *L2Storage) Get(ctx context.Context, key string) (*Entry, error)

func (*L2Storage) Set added in v0.27.85

func (s *L2Storage) Set(ctx context.Context, key string, entry *Entry) error

type LRUStorage

type LRUStorage struct {
	// contains filtered or unexported fields
}

LRUStorage wraps ShardedByteLRU and implements Storage. It owns all cache semantics (serialisation, TTL expiry); ShardedByteLRU remains a pure byte store.

func NewLRUStorage

func NewLRUStorage(totalMaxBytes int64, onEvict func(), m metrics.Metrics) *LRUStorage

NewLRUStorage returns an LRUStorage backed by a ShardedByteLRU sized to totalMaxBytes. m records the lru_oversized counter on oversized Set calls; pass metrics.Default when no test-scoped collector is needed.

func (*LRUStorage) Delete

func (s *LRUStorage) Delete(_ context.Context, key string) error

func (*LRUStorage) Get

func (s *LRUStorage) Get(_ context.Context, key string) (*Entry, error)

func (*LRUStorage) Set

func (s *LRUStorage) Set(_ context.Context, key string, entry *Entry) error

type Options added in v0.27.85

type Options struct {
	MaxBytes   int64            // maximum number of bytes the in-process LRU (L1) is allowed to hold across all cached entries
	ListenAddr string           // Skipper's own address; revalidation requests loop back through it so the full filter chain runs
	NetOpts    skpnet.Options   // HTTP client options for background worker that re-fetches stale entries from origin
	L2Client   L2Client         // optional L2 cache; nil = in-process LRU only
	IsNoL2Err  func(error) bool // returns true if no L2Client error
	L1TTL      time.Duration    // max TTL for write-through L1 warming; 0 = write-around
	Metrics    metrics.Metrics  // nil defaults to metrics.Default
}

Options configures the cache filter.

type ShardedByteLRU

type ShardedByteLRU struct {
	// contains filtered or unexported fields
}

ShardedByteLRU manages an array of LRU shards to reduce lock contention in highly concurrent reverse proxy environments.

func NewShardedByteLRU

func NewShardedByteLRU(totalMaxBytes int64, onEvict func()) *ShardedByteLRU

NewShardedByteLRU distributes total allowed memory evenly across all shards.

func (*ShardedByteLRU) Bytes

func (s *ShardedByteLRU) Bytes() int64

Bytes returns the total number of bytes currently stored across all shards.

func (*ShardedByteLRU) Delete

func (s *ShardedByteLRU) Delete(key string)

func (*ShardedByteLRU) ExceedsShard

func (s *ShardedByteLRU) ExceedsShard(data []byte) bool

ExceedsShard reports whether data is too large to fit in any shard.

func (*ShardedByteLRU) Get

func (s *ShardedByteLRU) Get(key string) ([]byte, bool)

func (*ShardedByteLRU) Set

func (s *ShardedByteLRU) Set(key string, data []byte)

type Storage

type Storage interface {
	// Get returns the entry for key, or (nil, nil) if the key is not found.
	Get(ctx context.Context, key string) (*Entry, error)

	// Set stores or overwrites the entry for key.
	Set(ctx context.Context, key string, entry *Entry) error

	// Delete removes the entry for key. It is not an error if the key does not exist.
	Delete(ctx context.Context, key string) error
}

Storage is the backing store abstraction for cached entries. Implementations must be safe for concurrent use.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL