Documentation
¶
Overview ¶
Package cache is the runtime counterpart of the `nucleus createcachetable` CLI command: a minimal key/value cache with TTL semantics, an in-memory backend for single-process deployments, and a SQL backend wired to the table that command creates (`nucleus_cache_entries` by default) for multi-replica deployments that share a database.
Lifecycle: experimental (see docs/reference/API_CONTRACT_INVENTORY.md). The surface may still grow (a Redis backend, GetOrSet helpers) before it freezes. Pure stdlib.
Index ¶
Constants ¶
const DefaultTableName = "nucleus_cache_entries"
DefaultTableName is the table `nucleus createcachetable` creates when no --table override is given, and the table NewSQL uses when SQLOptions.Table is empty. The CLI and this package share the constant on purpose: the command and the runtime must not drift apart.
Variables ¶
var ( // ErrEmptyKey is returned when a cache operation receives an empty key. ErrEmptyKey = errors.New("cache: key cannot be empty") // ErrNonPositiveTTL is returned by Set when ttl <= 0. The backing table // requires an expiry for every entry; an entry that must never expire // does not belong in a cache. ErrNonPositiveTTL = errors.New("cache: ttl must be greater than zero") )
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache interface {
Get(ctx context.Context, key string) ([]byte, bool, error)
Set(ctx context.Context, key string, value []byte, ttl time.Duration) error
Delete(ctx context.Context, key string) error
}
Cache is the minimal contract both backends implement.
Get returns (value, true, nil) for a live entry and (nil, false, nil) for a missing or expired one — an expired entry is indistinguishable from an absent one on purpose. Set stores value under key for ttl; a second Set on the same key replaces the value and its expiry. Delete removes an entry; deleting an absent key is not an error.
type Memory ¶
type Memory struct {
// contains filtered or unexported fields
}
Memory is an in-process Cache backend. It is safe for concurrent use and suitable for single-replica deployments; replicas do NOT share it — use the SQL backend (or an external store) when running more than one server process (see docs/guides/DEPLOYMENT_GUIDE.md, shared-state table).
Expired entries are dropped lazily: Get treats them as absent and deletes them, and every sweepEvery-th Set sweeps the whole map (amortised, so a write-heavy cache does not pay O(n) per Set). There is no background janitor goroutine, so a Memory cache needs no shutdown call. Call PruneExpired from your own maintenance schedule for tighter bounds.
func (*Memory) PruneExpired ¶
PruneExpired removes every expired entry and returns how many it removed.
type SQL ¶
type SQL struct {
// contains filtered or unexported fields
}
SQL is a Cache backed by the table `nucleus createcachetable` creates. It shares state across replicas that point at the same database, which makes it the SQL-backed option in the deployment guide's shared-state table. Expiry is enforced on read (expired rows are invisible to Get) and reclaimed by PruneExpired; expired rows that are never pruned only cost storage, never correctness.
mssql and oracle support follows the exploratory posture of those CI lanes (docs/governance/CI_MATRIX.md): the statements are exercised against sqlite/postgresql/mysql in CI, and take a transactional delete+insert path on mssql/oracle instead of a native upsert.
func NewSQL ¶
func NewSQL(db *sql.DB, opts SQLOptions) (*SQL, error)
NewSQL builds a SQL cache over db. The table (SQLOptions.Table, default DefaultTableName) must have the schema `nucleus createcachetable` creates: cache_key, value, expires_at, created_at, updated_at. NewSQL validates its inputs but does not touch the database; a missing table surfaces as an error from the first Get/Set.
func (*SQL) Get ¶
Get implements Cache. Expired rows are filtered server-side against the database clock, so a stale replica clock cannot resurrect an entry.
func (*SQL) PruneExpired ¶
PruneExpired deletes every expired row and returns how many it removed. Run it from a scheduled task or cron; Get never returns expired rows, so pruning is a storage-reclamation concern, not a correctness one.
type SQLOptions ¶
type SQLOptions struct {
// Table is the cache table name. Empty means DefaultTableName — the
// table `nucleus createcachetable` creates. The table must already
// exist; run the command (or ship its DDL as a migration) first.
Table string
// System is the SQL system the *sql.DB speaks, using the same names
// `(*db.DB).System()` returns: "sqlite", "postgresql", "mysql",
// "mssql", or "oracle". It selects placeholder style, upsert form,
// and the server-side UTC now() expression.
System string
}
SQLOptions configures NewSQL.