middleware

package
v1.7.1 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package middleware provides composable middleware for Grove KV operations.

Each middleware implements hook.PreQueryHook and/or hook.PostQueryHook and is registered via kv.WithHook() during store creation.

Index

Constants

This section is empty.

Variables

View Source
var ErrCircuitOpen = errors.New("kv: circuit breaker is open")

ErrCircuitOpen is returned when the circuit breaker is open.

Functions

This section is empty.

Types

type CacheHook

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

CacheHook provides a local in-memory L1 cache in front of the remote store. It supports read-through (check local first, then remote) and write-through (write to both local and remote on Set).

func NewCache

func NewCache(maxEntries int, defaultTTL time.Duration) *CacheHook

NewCache creates a new L1 cache middleware. maxEntries limits cache size; defaultTTL sets TTL for cached entries.

func (*CacheHook) AfterQuery

func (h *CacheHook) AfterQuery(_ context.Context, qc *hook.QueryContext, result any) error

func (*CacheHook) BeforeQuery

func (h *CacheHook) BeforeQuery(_ context.Context, qc *hook.QueryContext) (*hook.HookResult, error)

func (*CacheHook) Evict

func (h *CacheHook) Evict(keys ...string)

Evict removes a key from the L1 cache.

func (*CacheHook) Flush

func (h *CacheHook) Flush()

Flush clears the entire L1 cache.

func (*CacheHook) Put

func (h *CacheHook) Put(key string, value []byte, ttl time.Duration)

Put adds a value to the L1 cache.

func (*CacheHook) Size

func (h *CacheHook) Size() int

Size returns the current number of entries in the cache.

type CircuitBreakerHook

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

CircuitBreakerHook protects against cascading failures when the backing store is unavailable.

func NewCircuitBreaker

func NewCircuitBreaker(threshold int, timeout time.Duration) *CircuitBreakerHook

NewCircuitBreaker creates a new circuit breaker middleware.

threshold is the number of consecutive failures before opening the circuit. timeout is the duration the circuit stays open before transitioning to half-open.

func (*CircuitBreakerHook) BeforeQuery

func (*CircuitBreakerHook) RecordFailure

func (h *CircuitBreakerHook) RecordFailure()

RecordFailure records a failed operation, potentially opening the circuit.

func (*CircuitBreakerHook) RecordSuccess

func (h *CircuitBreakerHook) RecordSuccess()

RecordSuccess records a successful operation, potentially closing the circuit.

func (*CircuitBreakerHook) State

func (h *CircuitBreakerHook) State() CircuitState

State returns the current circuit breaker state.

type CircuitState

type CircuitState int

CircuitState represents the state of the circuit breaker.

const (
	// StateClosed means the circuit is healthy — requests flow normally.
	StateClosed CircuitState = iota
	// StateOpen means the circuit has tripped — requests are rejected immediately.
	StateOpen
	// StateHalfOpen means the circuit is testing — a limited number of requests are allowed.
	StateHalfOpen
)

type CompressHook

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

CompressHook provides transparent value compression/decompression.

func NewCompress

func NewCompress(algo CompressionAlgorithm, threshold ...int) *CompressHook

NewCompress creates a new compression middleware. The threshold is the minimum value size in bytes before compression is applied. A threshold of 0 compresses all values.

func (*CompressHook) AfterQuery

func (h *CompressHook) AfterQuery(_ context.Context, qc *hook.QueryContext, result any) error

func (*CompressHook) BeforeQuery

func (h *CompressHook) BeforeQuery(_ context.Context, qc *hook.QueryContext) (*hook.HookResult, error)

func (*CompressHook) Compress

func (h *CompressHook) Compress(data []byte) ([]byte, error)

Compress compresses data using the configured algorithm.

func (*CompressHook) Decompress

func (h *CompressHook) Decompress(data []byte) ([]byte, error)

Decompress decompresses data if it was compressed.

type CompressionAlgorithm

type CompressionAlgorithm int

CompressionAlgorithm identifies a compression algorithm.

const (
	// Gzip uses gzip compression (widely supported, good compression ratio).
	Gzip CompressionAlgorithm = iota
)

type EncryptHook

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

EncryptHook provides transparent AES-GCM encryption for values at rest.

func NewEncrypt

func NewEncrypt(key []byte) (*EncryptHook, error)

NewEncrypt creates a new encryption middleware with the given AES key. The key must be 16, 24, or 32 bytes for AES-128, AES-192, or AES-256.

func (*EncryptHook) Decrypt

func (h *EncryptHook) Decrypt(ciphertext []byte) ([]byte, error)

Decrypt decrypts ciphertext using AES-GCM.

func (*EncryptHook) Encrypt

func (h *EncryptHook) Encrypt(plaintext []byte) ([]byte, error)

Encrypt encrypts plaintext using AES-GCM.

type LoggingHook

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

LoggingHook logs every KV operation with structured fields.

func NewLogging

func NewLogging(logger log.Logger) *LoggingHook

NewLogging creates a new logging middleware.

func (*LoggingHook) AfterQuery

func (h *LoggingHook) AfterQuery(ctx context.Context, qc *hook.QueryContext, result any) error

func (*LoggingHook) BeforeQuery

func (h *LoggingHook) BeforeQuery(ctx context.Context, qc *hook.QueryContext) (*hook.HookResult, error)

type NamespaceHook

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

NamespaceHook automatically prepends a prefix to all keys. This is useful for multi-tenant isolation at the key level.

func NewNamespace

func NewNamespace(prefix string, separator ...string) *NamespaceHook

NewNamespace creates a namespace middleware that prepends the given prefix to all keys (e.g., "tenant:acme" → "tenant:acme:user:123").

func (*NamespaceHook) BeforeQuery

func (h *NamespaceHook) BeforeQuery(_ context.Context, qc *hook.QueryContext) (*hook.HookResult, error)

type RetryHook

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

RetryHook provides automatic retry with configurable backoff for transient failures.

func NewRetry

func NewRetry(maxAttempts int, opts ...RetryOption) *RetryHook

NewRetry creates a retry middleware with the given maximum attempts.

func (*RetryHook) AfterQuery

func (h *RetryHook) AfterQuery(_ context.Context, qc *hook.QueryContext, result any) error

func (*RetryHook) BackoffDuration

func (h *RetryHook) BackoffDuration(attempt int) time.Duration

BackoffDuration calculates the backoff duration for the given attempt (0-indexed).

func (*RetryHook) MaxAttempts

func (h *RetryHook) MaxAttempts() int

MaxAttempts returns the configured maximum number of retry attempts.

type RetryOption

type RetryOption func(*RetryHook)

RetryOption configures the retry middleware.

func WithInitialWait

func WithInitialWait(d time.Duration) RetryOption

WithInitialWait sets the initial wait duration before the first retry.

func WithJitter

func WithJitter(enabled bool) RetryOption

WithJitter enables or disables random jitter on retry delays.

func WithMaxWait

func WithMaxWait(d time.Duration) RetryOption

WithMaxWait sets the maximum wait duration between retries.

type StampedeHook

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

StampedeHook provides singleflight-based cache stampede protection. When multiple goroutines request the same key concurrently, only one performs the actual fetch; others wait and share the result.

func NewStampede

func NewStampede() *StampedeHook

NewStampede creates a new stampede protection middleware.

func (*StampedeHook) BeforeQuery

func (h *StampedeHook) BeforeQuery(_ context.Context, qc *hook.QueryContext) (*hook.HookResult, error)

func (*StampedeHook) Complete

func (h *StampedeHook) Complete(key string)

Complete signals that the GET for this key is done. This should be called after the operation completes.

Jump to

Keyboard shortcuts

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