kv

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2026 License: EUPL-1.2 Imports: 6 Imported by: 0

Documentation

Overview

Package kv is a small Redis-style key/value store with per-entry TTLs. Values are opaque bytes (JSON records, encrypted snapshots, or at-rest ciphertext); each entry may carry an opaque metadata descriptor so reads can dispatch parsing/decryption per value. Callers handle their own (de)serialization. The store is the single persistence primitive for the authorization server, the bff, and the nonce service — multi-index lookups are modelled with secondary-index keys (a record under "<ns>:<id>" plus "<ns>:<field>:<v>" keys holding the id).

This package has no external dependencies: it ships the interface and the in-memory backend (NewMemory — the default for tests and dev). The Postgres backend lives in the sibling kvpg module so that importing kv never pulls in a database driver; only code that wires Postgres imports kvpg. Consumers accept the kv.Store interface (the duck type), not a concrete backend.

Atomicity: Take (get+delete) and SetMany (multi-key write) are atomic, which the security-critical single-use (nonce redeem, authorization-code exchange) and index-consistency operations rely on.

Index

Constants

This section is empty.

Variables

View Source
var ErrClosed = errors.New("kv: store closed")

ErrClosed is returned by every method after Close.

Functions

This section is empty.

Types

type Bus

type Bus interface {
	// Publish sends payload to every subscriber of channel, including in other processes.
	Publish(ctx context.Context, channel, payload string) error
	// Subscribe returns a stream of payloads published to channel until ctx is cancelled (then it is closed).
	Subscribe(ctx context.Context, channel string) (<-chan string, error)
	// Close releases resources.
	Close() error
}

Bus is a lightweight publish/subscribe channel for small control messages (e.g. session revocations), fanned out to every subscriber across processes. Like Store, the interface lives here (no driver) and the Postgres backend (LISTEN/NOTIFY) lives in kv/postgres. Delivery is best-effort: a slow or briefly disconnected subscriber may miss a message, so callers must not rely on the bus alone for correctness (pair it with a durable backstop).

func NewMemBus

func NewMemBus() Bus

NewMemBus returns an in-process Bus.

type Entry

type Entry struct {
	Key      string
	Value    []byte
	TTL      time.Duration
	Metadata []byte
}

Entry is one key/value/TTL triple for SetMany. A zero TTL means no expiry. Metadata is an optional, opaque descriptor stored alongside the value (e.g. a codec / encryption-scheme tag) so reads can dispatch parsing/decryption per value rather than via a global flag; nil leaves it unset.

type Item

type Item struct {
	Value    []byte
	Metadata []byte
}

Item is a value plus its optional metadata descriptor, returned by GetItem.

type Store

type Store interface {
	// Get returns the value for key. found is false when the key is absent or expired.
	Get(ctx context.Context, key string) (value []byte, found bool, err error)

	// GetItem returns the value and its metadata descriptor (the per-entry Metadata written via SetMany) for
	// key. found is false when the key is absent or expired.
	GetItem(ctx context.Context, key string) (item Item, found bool, err error)

	// Set stores value under key with an optional TTL (0 = no expiry), overwriting any existing value.
	Set(ctx context.Context, key string, value []byte, ttl time.Duration) error

	// SetMany writes all entries atomically (one transaction), used to keep a record and its
	// secondary-index keys consistent.
	SetMany(ctx context.Context, entries ...Entry) error

	// Take atomically returns and deletes key — single-use semantics for nonce redemption and
	// authorization-code exchange. found is false when the key is absent or expired.
	Take(ctx context.Context, key string) (value []byte, found bool, err error)

	// Delete removes key. No error if it doesn't exist.
	Delete(ctx context.Context, key string) error

	// Keys returns all non-expired keys with the given prefix, sorted. The prefix is matched
	// literally (callers use wildcard-free namespace prefixes).
	Keys(ctx context.Context, prefix string) ([]string, error)

	// Cleanup removes expired entries and returns the count removed.
	Cleanup(ctx context.Context) (removed int, err error)

	// Close releases resources; subsequent calls return ErrClosed.
	Close() error
}

Store is the persistence interface. Implementations must be safe for concurrent use.

func NewMemory

func NewMemory() Store

NewMemory returns an in-memory Store — the default backend for tests and development. Data is lost on process exit; for durability use the Postgres backend (kvpg).

Directories

Path Synopsis
Package postgres is the PostgreSQL backend for the kv.Store interface.
Package postgres is the PostgreSQL backend for the kv.Store interface.

Jump to

Keyboard shortcuts

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