DialCache Go API

Generated with go doc -all from bae1e5e. Use your browser's Find command to locate a symbol.

package dialcache // import "github.com/lan17/DialCache/go"

Package dialcache provides explicitly enabled, layered caching with runtime
rollout, request coalescing, invalidation, stale recovery and shadow validation.

CONSTANTS

const (
	// DefaultSourceTimeout bounds a source call when Operation.SourceTimeout is zero.
	DefaultSourceTimeout = 60 * time.Second
	// DefaultRemoteReadTimeout bounds a remote read unless an option or policy overrides it.
	DefaultRemoteReadTimeout = 50 * time.Millisecond
	// NoTimeout disables the source deadline for one operation.
	NoTimeout time.Duration = -1
	// MaxSupportedDuration is the longest TTL, recovery age or future buffer: 365 days.
	MaxSupportedDuration = time.Duration(MaxSupportedDurationMS) * time.Millisecond
	// MaxDeadline is the longest source or read deadline.
	MaxDeadline = time.Duration(MaxDeadlineMS) * time.Millisecond
)
const DefaultCompressionThresholdBytes = 4096
const DefaultZstdLevel = 3
const InvalidationScript = `local function parse_safe_integer(raw)
  if not string.match(raw, "^%d+$") then return nil end
  local value = tonumber(raw)
  if not value or value > 9007199254740991 then return nil end
  return value
end
local future_buffer_ms = parse_safe_integer(ARGV[1])
if not future_buffer_ms or future_buffer_ms < 0 or future_buffer_ms > 31536000000 then
  return redis.error_reply("ERR invalid DialCache future buffer")
end
local invalidated_at_ms = parse_safe_integer(ARGV[2])
if not invalidated_at_ms or invalidated_at_ms > 9007199254740991 - future_buffer_ms then
  return redis.error_reply("ERR invalid DialCache invalidatedAtMs")
end
local proposed_watermark = invalidated_at_ms + future_buffer_ms
local raw_watermark = redis.pcall("GET", KEYS[1])
if type(raw_watermark) == "table" and raw_watermark.err then
  if not string.match(raw_watermark.err, "^WRONGTYPE ") then return raw_watermark end
  raw_watermark = false
end
local current_watermark = 0
if raw_watermark then
  local parsed_watermark = parse_safe_integer(raw_watermark)
  if parsed_watermark then current_watermark = parsed_watermark end
end
local watermark = math.max(current_watermark, proposed_watermark)
local current_ttl_ms = -2
if raw_watermark then current_ttl_ms = redis.call("PTTL", KEYS[1]) end
local desired_ttl_ms = math.max(7200000, watermark - invalidated_at_ms + 3600000 + 60000)
if current_ttl_ms > desired_ttl_ms then desired_ttl_ms = current_ttl_ms end
local encoded_watermark = string.format("%.0f", watermark)
if current_ttl_ms == -1 then
  redis.call("SET", KEYS[1], encoded_watermark)
else
  redis.call("SET", KEYS[1], encoded_watermark, "PX", desired_ttl_ms)
end
return 1`
    InvalidationScript is the version-1 wire invalidation transition. Redis
    Lua numbers exactly represent the accepted safe-integer domain. Invalid
    arguments return before GET/repair; wrong-type keys alone are repairable
    read failures.

const JSONUndefinedSentinel = "__dialcache_json_undefined_v1__"
const MaxDeadlineMS = int64(2147483647)
const MaxDecompressedBytes = 512 * 1024 * 1024
const MaxSafeInteger = uint64(9007199254740991)
const MaxSupportedDurationMS = int64(31536000000)
const MaxTrackedValueTTLMS = int64(3600000)
const ShadowLogKeyMaxBytes = 2048
const ShadowLogTruncationMarker = "...[truncated]"
const ShadowLogValueMaxBytes = 8192

VARIABLES

var Absent = absentValue{1}
var ErrInvalidOperation = errors.New("dialcache: invalid operation")
    ErrInvalidOperation wraps operation validation failures other than policy.

var ErrInvalidOption = errors.New("dialcache: invalid option")
    ErrInvalidOption wraps constructor option validation failures.

var ErrInvalidPolicy = errors.New("dialcache: invalid policy")
    ErrInvalidPolicy wraps static policy validation failures.

var ErrNoRemote = errors.New("dialcache: a remote adapter is required")
    ErrNoRemote reports maintenance that needs a remote adapter.

var ErrReservedUseCase = errors.New("dialcache: reserved use case \"watermark\"")
    ErrReservedUseCase reports the reserved use case "watermark".

var ErrUseCaseRegistered = errors.New("dialcache: use case is already registered")
    ErrUseCaseRegistered reports a second Cached registration of a use case.

var ErrValueType = errors.New("dialcache: cached value has a different type than requested")
    ErrValueType reports a shared in-process value of a different Go type.


FUNCTIONS

func Cached[T, Arg any](cache *Cache, op Operation[T], selectKey func(Arg) (Identity, error), source func(context.Context, Arg) (T, error)) (func(context.Context, Arg) (T, error), error)
    Cached registers a use case once and returns its typed read-through
    function. The key selector runs only for an enabled call and supplies the
    ID and Args; KeyType, UseCase, Tracked and Namespace come from op.Identity.
    The static policy and source timeout are captured at registration.

func CeilSupportedCacheTTLMS(value float64) (int64, error)
    CeilSupportedCacheTTLMS is the adapter-level duration boundary. Fractional
    milliseconds round up, before checking the positive, 365-day limit.

func Cohort(logical, discriminator string) float64
    Cohort preserves FNV-1a over UTF-16 code units, including surrogate pairs.

func EncodeFrame(frame Frame) ([]byte, error)
    EncodeFrame accepts only the writer timestamp domain. DecodeFrame retains
    uint64 precision and leaves the additional safe-timestamp check to the core.

func FailureIsolatedObserver(observer func(Event) error) func(Event)
    FailureIsolatedObserver adapts a fallible exporter for WithObserver.
    Neither a returned error nor a panic may replace a source result or start
    cache work.

func GetOrLoad[T any](ctx context.Context, c *Cache, op Operation[T], load func(context.Context) (T, error)) (T, error)
    GetOrLoad executes one inline loader through the cache chain without
    registering its use case. Outside an enabled scope it calls load directly.
    Returned in-memory values are shared and must be treated as immutable.

func IsAbsent(value any) bool
func NormalizeArgs(args map[string]any) ([][2]string, error)
    NormalizeArgs omits Absent, converts the supported scalar domain using the
    JavaScript String rules, and orders names lexicographically by UTF-16 units.
    Arbitrary precision integers use big.Int; objects and arrays are rejected.

func PreviewShadowLogKey(value string) string
func Ptr[T any](v T) *T
    Ptr returns a pointer to v, for optional Policy and PolicyOverlay leaves.

func ReadBudget(ctx context.Context) (time.Duration, bool)
    ReadBudget reports the remote read deadline attached to an adapter context.

func SemanticEqual(left, right any) bool
    SemanticEqual is strict deep equality for the portable value domain:
    numbers are one IEEE-754 type, NaN equals NaN, signed zeros differ, object
    key order is irrelevant, and Absent differs from null. Byte payloads remain
    typed bytes.

func ValidatePolicy(p Policy) error
    ValidatePolicy checks a static policy; failures wrap ErrInvalidPolicy.

func ValidateRedisInvalidationReply(reply any) error
func ValidateRedisSetReply(reply any) error
func ValidateTimestampMS(value float64) (uint64, error)

TYPES

type Cache struct {
	// Has unexported fields.
}
    Cache is one DialCache instance: a process-local LRU, coalescing table,
    shadow slots and use case registry shared by every value type.

func MustNew(opts ...Option) *Cache
    MustNew is New for configuration known to be valid; it panics otherwise.

func New(opts ...Option) (*Cache, error)
    New constructs a cache. Options are applied in order; an invalid option
    returns an error wrapping ErrInvalidOption.

func (c *Cache) Disable(ctx context.Context) context.Context
    Disable returns a context whose cached operations pass straight through to
    their sources. Enabling again inside it rejoins the surrounding live scope.

func (c *Cache) Enable(ctx context.Context) (context.Context, func())
    Enable returns a context in which cached operations participate, and the
    function that closes that request scope. Call it when the request's work
    is complete, typically with defer: it ends the request memo lifetime and
    prevents late publication into it. A context enabled inside a live scope
    shares that scope, and its close function does nothing. Retaining the
    context after close does not keep caching enabled. Context cancellation
    remains an application and source concern.

func (c *Cache) GetCoalescingState() CoalescingState
    GetCoalescingState reports actual process leaders, followers and the oldest
    leader's age for this instance.

func (c *Cache) Invalidate(ctx context.Context, identity Identity, futureBuffer time.Duration) (err error)
    Invalidate raises the remote watermark for every tracked value of the entity
    named by identity's KeyType and ID, so frames stamped at or before the
    invalidation plus futureBuffer are no longer served. It requires a remote
    adapter and returns its error. Local entries expire by TTL.

func (c *Cache) IsEnabled(ctx context.Context) bool
    IsEnabled reports whether operations with ctx participate in caching.

func (c *Cache) WithDisabled(ctx context.Context, fn func(context.Context) error) error
    WithDisabled runs fn with caching disabled.

func (c *Cache) WithEnabled(ctx context.Context, fn func(context.Context) error) error
    WithEnabled runs fn inside an enabled scope that closes when fn returns.

type CallbackPanicError struct{ Value any }

func (e *CallbackPanicError) Error() string

type Clock interface {
	WallMS() int64
	ElapsedMS() int64
}
    Clock separates wall timestamps from elapsed-time expiration and deadlines.

type CoalescingState struct{ Process ProcessCoalescingState }

type Codec[T any] interface {
	Encode(T) (Payload, error)
	Decode(Payload) (T, error)
}
    Codec borrows immutable payloads. Every Decode must produce an independent
    value.

type CompressionConfig struct {
	ThresholdBytes int
	Level          int
}

func ResolveCompressionConfig(config *CompressionConfig) (CompressionConfig, error)

type CompressionReadResult struct {
	Payload Payload
	Outcome string
}

func DecompressPayload(payload Payload, limit ...int) CompressionReadResult

type CompressionWriteResult struct {
	Payload                    Payload
	Outcome                    string
	OriginalBytes, StoredBytes int
}

func CompressPayload(payload Payload, config CompressionConfig, limit ...int) (CompressionWriteResult, error)

type ContextCodec[T any] interface {
	EncodeContext(context.Context, T) (Payload, error)
	DecodeContext(context.Context, Payload) (T, error)
}

type DatadogMetrics struct {
	// Has unexported fields.
}

func NewDatadogMetrics(options DatadogMetricsOptions) (*DatadogMetrics, error)

func (adapter *DatadogMetrics) ObserveEvent(event Event) error

type DatadogMetricsOptions struct {
	Client                DogStatsDClient
	ObservationMetricType string
	Namespace             string
	NamespaceSet          bool // distinguish an explicitly empty namespace from omission
}

type DeferredExecutor interface{ Defer(func()) }
    DeferredExecutor controls detached work admission without changing its
    rules.

type DogStatsDClient interface {
	Increment(name string, value float64, tags map[string]string) error
	Histogram(name string, value float64, tags map[string]string) error
	Distribution(name string, value float64, tags map[string]string) error
}
    DogStatsDClient leaves transport, buffering, flushing and ownership with
    the caller. Both observation methods are required, matching the TypeScript
    adapter.

type Event struct {
	Kind    string
	Scope   string
	Key     string
	Data    map[string]any
	Seconds float64
	Bytes   int64
	Outcome string
}
    Event records public diagnostics; Data contains the backend-neutral labels.

type FallbackTimeoutError struct {
	UseCase string
	Timeout time.Duration
}

func (e *FallbackTimeoutError) Error() string

type Frame struct {
	CreatedAtMS uint64
	Binary      bool
	Payload     []byte
}

type Identity struct {
	Namespace string      `json:"namespace"`
	KeyType   string      `json:"keyType"`
	ID        string      `json:"id"`
	UseCase   string      `json:"useCase"`
	Tracked   bool        `json:"trackForInvalidation"`
	Args      [][2]string `json:"args"`
}
    Identity is an already normalized logical identity. Ordered arguments retain
    caller order; normalization of host-language objects is a separate profile.

func (id Identity) Keys() (logical, value, watermark string, err error)

func (id *Identity) UnmarshalJSON(raw []byte) error
    UnmarshalJSON rejects isolated UTF-16 escapes before encoding/json replaces
    them. The Go API uses Unicode scalar strings; this is its fixture boundary.

type JSONCodec[T any] struct{}
    JSONCodec implements the default JSON serializer over JSON-compatible
    Go values and Absent. Object members holding Absent are omitted; array
    elements holding Absent and nonfinite numbers become null. Big integers
    and cycles are errors. Strings contain Unicode scalar values; JSON escapes
    with unpaired UTF-16 surrogates are rejected. JSONCodec[any] preserves this
    supported domain.

func (JSONCodec[T]) Decode(payload Payload) (T, error)

func (JSONCodec[T]) Encode(value T) (Payload, error)

type JSONMember struct {
	Name  string
	Value any
}
    JSONMember and JSONObject preserve object insertion order when
    byte-identical JSON output matters. Integer-index names are emitted first,
    as in JavaScript. A Go map has no insertion order; its other names are
    emitted in UTF-16 order.

type JSONObject []JSONMember

type JSONPolicy map[string]any
    JSONPolicy is a runtime overlay in the JSON configuration shape shared
    with TypeScript: ttlSec and ramp layer maps, requestLocal, coalesce,
    staleOnErrorMaxAgeSec, remoteReadTimeoutMs and shadow. Explicit null leaves
    are invalid; Absent leaves inherit.

type Logger interface {
	Debug(message string, details any)
	Warn(message string, details any)
	Error(message string, details any)
}

func FailureIsolatedLogger(logger Logger) Logger

type MetricsAdapter interface{ ObserveEvent(Event) error }
    MetricsAdapter consumes only the bounded public diagnostic events. Event.Key
    is never a metric label; exporting logical identities would add cardinality.

type MismatchDiffLevel string
    MismatchDiffLevel is how much of the structural difference between the
    compared values a confirmed-mismatch warning logs.

const (
	// MismatchDiffOff logs no difference.
	MismatchDiffOff MismatchDiffLevel = "off"
	// MismatchDiffPaths logs the RFC 6901 JSON Pointers of the differing fields.
	MismatchDiffPaths MismatchDiffLevel = "paths"
	// MismatchDiffValues logs those pointers with the cached and source values
	// at each one.
	MismatchDiffValues MismatchDiffLevel = "values"
)
type MismatchEntry struct {
	Path           string
	Cached, Source any
}
    MismatchEntry is one differing field of a confirmed shadow mismatch: an RFC
    6901 JSON Pointer into the compared value and the value on each side there.
    Absent omits a side the field does not have, as the built-in computation
    does for a member present on one side only; set both sides to Absent when
    only the location is known. A nil side is JSON null.

    A side renders as JSONCodec writes it, except that a value implementing
    json.Marshaler, json.RawMessage included, renders at any depth as its
    MarshalJSON output parsed back, so a type that redacts itself stays redacted
    in diffJson. As in encoding/json, a pointer's MarshalJSON runs only for
    an addressable value, such as a slice element. A side with no rendering
    (a cycle, a *big.Int, a function, or a MarshalJSON that fails, panics or
    returns output that is not JSON or holds a number outside double range) logs
    a null diffJson with render_error and keeps the paths.

type MismatchLoggingPolicy struct {
	// Value includes bounded native JSON of both compared values.
	Value *bool
	// Diff includes the differing fields at this level.
	Diff *MismatchDiffLevel
}
    MismatchLoggingPolicy selects what a confirmed-mismatch warning carries.
    The warning is emitted when Value is true or Diff is above MismatchDiffOff.
    Nil leaves inherit, and runtime overlays merge each leaf independently.

type Operation[T any] struct {
	Identity Identity
	// IdentityProvider computes the identity per invocation; Cached sets it from
	// the key selector. A failing or reserved computed identity fails open.
	IdentityProvider func() (Identity, error)
	Policy           Policy
	// Codec overrides JSONCodec[T] for this operation's remote payloads.
	Codec Codec[T]
	// SourceTimeout bounds the source call. It must be whole milliseconds; zero
	// means DefaultSourceTimeout and NoTimeout disables the deadline.
	SourceTimeout time.Duration
	// ShouldRecover replaces the instance recovery predicate for this operation.
	ShouldRecover RecoveryPredicate
	// Comparator decides shadow matches; nil compares with SemanticEqual.
	Comparator func(cached, source T) (bool, error)
	// MismatchDiff replaces the built-in JSON difference computation behind
	// the mismatchPaths and diffJson fields of confirmed-mismatch warnings; it
	// runs only when the resolved mismatch-logging diff level is above
	// MismatchDiffOff. Inputs are borrowed snapshots. Like Comparator, it must
	// be deterministic, side-effect-free, non-mutating and bounded. A returned
	// error or panic logs null for the paths and the diff, without falling back
	// to the built-in computation; a nil slice is an empty list.
	MismatchDiff func(cached, source T) ([]MismatchEntry, error)
}
    Operation describes one cached computation producing values of type T.

type Option func(*settings) error
    Option configures New. Unset options keep the documented defaults.

func WithClock(clock Clock) Option
    WithClock replaces the wall and elapsed clock, mainly for tests.

func WithCompression(config CompressionConfig) Option
    WithCompression sets the write-side compression policy. Zero fields keep
    the 4,096-byte threshold and zstd level 3. Reads always accept compressed
    payloads.

func WithLocalCapacity(entries int) Option
    WithLocalCapacity bounds process-local entries across every use case;
    the default is 10,000. Zero disables local storage while keeping coalescing.

func WithLogger(logger Logger) Option
    WithLogger replaces the standard logger. Logger failures are isolated.

func WithMetrics(adapter MetricsAdapter) Option
    WithMetrics connects a MetricsAdapter such as the Prometheus or DogStatsD
    adapter, isolating its errors and panics from cache and source results.

func WithNamespace(namespace string) Option
    WithNamespace sets the logical key namespace; the default is "urn". An empty
    namespace is permitted. Braces are reserved for Redis Cluster hash tags.

func WithObserver(observe func(Event)) Option
    WithObserver receives every backend-neutral diagnostic event. Every
    configured observer and metrics adapter receives each event; panics in an
    observer are ignored.

func WithPolicyProvider(provider PolicyProvider) Option
    WithPolicyProvider resolves a sparse runtime policy overlay once per enabled
    invocation. A nil overlay inherits the operation's static policy.

func WithRecoveryOutcomes(hook func(Event)) Option
    WithRecoveryOutcomes receives each stale recovery outcome.

func WithRemote(remote Remote) Option
    WithRemote supplies the shared layer. Without it the cache is local only.

func WithRemoteReadTimeout(timeout time.Duration) Option
    WithRemoteReadTimeout sets the instance remote read deadline in whole
    milliseconds; the default is 50 ms. Policy can override it per use case.

func WithShadowCapacity(jobs int) Option
    WithShadowCapacity bounds scheduled or running shadow jobs per instance;
    the default is one. Excess jobs are dropped and reported.

func WithShadowOutcomes(hook func(Event)) Option
    WithShadowOutcomes receives each shadow validation verdict and enables
    shadow admission; without a hook no shadow work is scheduled.

func WithStaleRecovery(predicate RecoveryPredicate) Option
    WithStaleRecovery sets the instance default for which source errors may
    serve a retained stale value. Omitted, only FallbackTimeoutError qualifies.

func WithoutCompression() Option
    WithoutCompression stores every payload uncompressed. Reads still decompress
    marked payloads.

type Payload struct {
	Bytes  []byte
	Binary bool
}

func EscapeRawPayload(payload Payload) Payload

type Policy struct {
	// RequestLocal memoizes successful values for the enabled scope's lifetime.
	RequestLocal bool
	// LocalTTL and RemoteTTL enable a layer with an insertion TTL in whole seconds.
	LocalTTL  time.Duration
	RemoteTTL time.Duration
	// LocalRamp and RemoteRamp are cohort percentages from 0 through 100; nil means 100.
	LocalRamp  *float64
	RemoteRamp *float64
	// Coalesce shares one in-flight execution across same-key callers; nil means true.
	Coalesce *bool
	// StaleOnErrorMaxAge is the exclusive age ceiling for serving a retained
	// remote value after an eligible source error. It must exceed RemoteTTL.
	// Nil omits recovery; an explicit zero disables an inherited policy.
	StaleOnErrorMaxAge *time.Duration
	// RemoteReadTimeout overrides the instance remote read deadline.
	RemoteReadTimeout *time.Duration
	Shadow            *ShadowPolicy
}
    Policy is an operation's static policy. Zero TTLs omit a layer; positive
    TTLs are whole seconds. Pointer leaves distinguish omitted settings,
    which inherit defaults and runtime overlays, from explicit zero or false.

func ParsePolicy(config any) (Policy, error)
    ParsePolicy accepts the static JSON-shaped TypeScript configuration.
    Explicit null leaves remain invalid; nil/Absent for the whole configuration
    means none.

func SnapshotPolicy(p Policy) Policy
    SnapshotPolicy detaches every optional leaf from mutable caller-owned
    memory.

type PolicyDefaults struct{ RemoteReadTimeout time.Duration }

type PolicyOverlay struct {
	RequestLocal       *bool
	LocalTTL           *time.Duration
	RemoteTTL          *time.Duration
	LocalRamp          *float64
	RemoteRamp         *float64
	Coalesce           *bool
	StaleOnErrorMaxAge *time.Duration
	RemoteReadTimeout  *time.Duration
	Shadow             *ShadowPolicy
}
    PolicyOverlay is a typed sparse overlay. Nil leaves inherit. Durations must
    be whole seconds for TTLs and recovery ages and whole milliseconds for the
    read timeout; other values are treated as invalid leaves with the same
    narrow consequences as an invalid JSON leaf.

type PolicyProvider func(context.Context, Identity) (RuntimePolicy, error)
    PolicyProvider returns a sparse runtime overlay for one invocation. A nil
    overlay inherits the static policy; an error bypasses caching for the call.

type PreciseClock interface {
	ElapsedTime() time.Duration
}
    PreciseClock optionally preserves fractional milliseconds for deadlines
    and diagnostics. Local TTL uses whole milliseconds from Clock.ElapsedMS.
    ElapsedTime and ElapsedMS must use the same monotonic origin. Existing
    integer clocks remain supported through Clock.ElapsedMS.

type ProcessCoalescingState struct {
	ActiveLeaders   int
	ActiveFollowers int
	// OldestLeaderAge is zero when no leader is active.
	OldestLeaderAge time.Duration
}
    ProcessCoalescingState reports the process-scoped single-flight table.

type PrometheusCollectorBinding struct {
	Schema    PrometheusCollectorSchema
	Collector prometheus.Collector
}
    PrometheusCollectorBinding makes an existing collector's schema explicit.
    Collector must be an individually registered CounterVec or HistogramVec.
    Schema is the caller's assertion about its construction options, including
    histogram buckets: client_golang does not expose those options for an empty
    HistogramVec. The adapter checks the declared schema and public descriptor
    before reuse, without creating a temporary metric series.

type PrometheusCollectorSchema struct {
	Kind, Name, Help string
	Labels           []string
	Buckets          []float64
}
    PrometheusCollectorSchema fixes the TypeScript adapter wire contract.

func PrometheusCollectorSchemas(prefix string) []PrometheusCollectorSchema

type PrometheusMetrics struct {
	// Has unexported fields.
}

func NewPrometheusMetrics(registry *prometheus.Registry, prefix string) (*PrometheusMetrics, error)
    NewPrometheusMetrics creates collectors or reuses an earlier DialCache
    group. Use NewPrometheusMetricsWithBindings to reuse externally created
    collectors.

func NewPrometheusMetricsWithBindings(registry *prometheus.Registry, prefix string, bindings []PrometheusCollectorBinding) (adapter *PrometheusMetrics, err error)
    NewPrometheusMetricsWithBindings validates every supplied binding before
    atomically registering the remaining collectors. Previously observed values
    remain on the same collector objects. As with registry configuration itself,
    callers must not concurrently unregister/reconfigure the supplied collectors
    during construction; concurrent observations remain safe.

func (adapter *PrometheusMetrics) ObserveEvent(event Event) error

type ReadResult struct {
	Kind                string
	Reason              string
	ObservedWatermarkMS *uint64
	Frame               Frame
	// RawSet marks an untrusted semantic adapter result, including explicit nil.
	Raw    any
	RawSet bool
}

func DecodeFrame(raw []byte, tracked bool, watermark *string) ReadResult
    DecodeFrame implements the protocol's classification precedence. A nil raw
    value is absent; a present zero-length value is an unclassified miss.

func NormalizeReadResult(result ReadResult, tracked bool) ReadResult
    NormalizeReadResult is the core trust boundary, above wire decoding. Miss
    reason and refill fence are validated independently. Frame-shaped objects
    ignore stray miss metadata; only kind:"miss" selects the miss branch.

func RawReadResult(value any) ReadResult

func (r ReadResult) Error() error

type RecoveryPredicate func(error) (bool, error)
    RecoveryPredicate decides whether one source error may serve a retained
    stale value. A returned error or panic denies recovery.

type RedisAdapter struct {
	// Has unexported fields.
}
    RedisAdapter borrows a connected, caller-owned go-redis standalone,
    Sentinel, or Cluster client. It never connects/closes the client or changes
    its options. Set finite client dial/read/write/retry budgets. Cancellation
    after dispatch cannot prove a mutation did not execute; the cache bounds its
    own wait.

func NewRedisAdapter(client redis.UniversalClient) *RedisAdapter

func (adapter *RedisAdapter) Invalidate(ctx context.Context, key string, invalidatedAtMS, futureMS int64) error
    Invalidate keeps the caller's application-clock timestamp stable throughout
    one logical dispatch. EVALSHA failure gets one EVAL retry; accepted but
    invalid replies are errors and are never retried. The monotonic script is
    idempotent even if the first command executed before its response was lost.

func (adapter *RedisAdapter) InvalidateDecimal(ctx context.Context, key, futureMS, invalidatedAtMS string) error
    InvalidateDecimal exposes the script's raw decimal boundary for out-of-band
    tooling and conformance replay. Validation inside Lua precedes every
    mutation.

func (adapter *RedisAdapter) Read(ctx context.Context, valueKey, watermarkKey string) (ReadResult, error)

func (adapter *RedisAdapter) Write(ctx context.Context, key string, frame Frame, ttl time.Duration) error
    Write performs exactly one native SET of the complete frame. It neither
    reads nor modifies the entity watermark. A provided timestamp is exact.

func (adapter *RedisAdapter) WriteMilliseconds(ctx context.Context, key string, frame Frame, ttlMS float64) error

type RedisPayloadError struct{ Message string }

func (e *RedisPayloadError) Error() string

type RedisProtocolError struct{ Message string }

func (e *RedisProtocolError) Error() string

type Remote interface {
	// Read returns the value at valueKey and, for a tracked read, the watermark
	// at watermarkKey from one atomic primary snapshot.
	Read(ctx context.Context, valueKey, watermarkKey string) (ReadResult, error)
	// Write stores one complete frame with the given TTL in a single native SET.
	Write(ctx context.Context, key string, frame Frame, ttl time.Duration) error
	// Invalidate raises the watermark to the invalidation timestamp plus the
	// future buffer. Both arguments are wire milliseconds.
	Invalidate(ctx context.Context, watermarkKey string, invalidatedAtMS, futureBufferMS int64) error
}
    Remote supplies atomic primary snapshots and complete, client-stamped
    writes. Cancellation requests do not assert that a pending command has
    stopped.

type RemoteReadTimeoutError struct{ Timeout time.Duration }

func (e *RemoteReadTimeoutError) Error() string

type ResolvedLayer struct {
	Enabled    bool
	Reason     string
	Configured bool // valid TTL and ramp remain available when ramp excludes the key
	TTL        time.Duration
	Ramp       float64
}

type ResolvedPolicy struct {
	RequestLocal            bool
	Coalesce                bool
	Local                   ResolvedLayer
	Remote                  ResolvedLayer
	RemoteReadTimeout       time.Duration
	StaleOnErrorMaxAge      time.Duration
	StaleOnErrorConfigError bool
	Shadow                  ResolvedShadow
}

func ResolvePolicy(base Policy, overlay RuntimePolicy, identity Identity, defaults PolicyDefaults) (ResolvedPolicy, error)
    ResolvePolicy merges sparse leaves once. A malformed container, boolean or
    read deadline is an invocation-wide error; TTL/ramp errors disable only that
    layer, while an invalid recovery option preserves valid remote serving.

type ResolvedShadow struct {
	Enabled bool // cohort selection only; admission still needs an eligible path and hook
	Ramp    float64
	// LogValue and LogDiff are the effective mismatch-logging leaves: each
	// layer's LogMismatches expands first, then the leaves merge, and an
	// invalid leaf acts off.
	LogValue    bool
	LogDiff     MismatchDiffLevel
	ConfigError bool
	// LoggingConfigError covers every invalid logging leaf and shorthand; record
	// it once, only if a job is admitted, as in TypeScript.
	LoggingConfigError bool
}

type RuntimePolicy interface {
	// Has unexported methods.
}
    RuntimePolicy is a sparse overlay applied over an operation's static policy:
    either a typed *PolicyOverlay or a JSONPolicy in the configuration shape
    shared with TypeScript.

func RawPolicy(value any) RuntimePolicy
    RawPolicy wraps an arbitrary decoded JSON value as a runtime overlay so a
    configuration service's reply can pass through unchanged. A value that is
    not an object is an invocation-wide policy error, as in TypeScript.

type ShadowPolicy struct {
	// Ramp is the shadow cohort percentage; nil and zero disable shadow work.
	Ramp *float64
	// LogMismatches is shorthand for the whole MismatchLogging group: true
	// stands for Value true and Diff MismatchDiffValues, false for both off.
	// Leaves set in this policy's MismatchLogging override what it expands to
	// before a runtime overlay merges.
	LogMismatches *bool
	// MismatchLogging selects the content of the one bounded warning emitted
	// per confirmed mismatch. Omitted leaves default off.
	MismatchLogging *MismatchLoggingPolicy
}
    ShadowPolicy configures detached remote shadow validation.

type Timer interface{ Stop() bool }

type TimerClock interface {
	AfterFunc(delayMS int64, callback func()) Timer
}
    TimerClock lets applications supply the timer source corresponding to Clock.
    Callbacks must run at most once; Stop prevents a callback which has not
    begun.