Documentation
¶
Overview ¶
Package postgres implements persistent cache using an explicitly migrated PostgreSQL table and borrowed Foundry connection. It never creates schema at application boot. Tags, batches and distributed fill leases are not supplied; Store.Invalidate physically removes a namespace's rows.
Index ¶
- Constants
- func Migrations() []migrate.Definition
- type Backend
- func (b *Backend) Access(ctx context.Context, key cache.EntryKey, mode cacheatomic.Mode, ...) error
- func (b *Backend) Add(ctx context.Context, key cache.EntryKey, data []byte, ttl cache.TTL) (bool, error)
- func (b *Backend) Close(ctx context.Context) error
- func (b *Backend) Done() <-chan struct{}
- func (b *Backend) FlushNamespace(ctx context.Context, namespace cache.Namespace) (uint64, error)
- func (b *Backend) Forget(ctx context.Context, key cache.EntryKey) (bool, error)
- func (*Backend) FoundryAdapter(frameworkadapter.Seal)
- func (b *Backend) Inspect(ctx context.Context, key cache.EntryKey, inspect cacheatomic.Inspection) (bool, error)
- func (b *Backend) Prune(ctx context.Context, limit int) (int, error)
- func (b *Backend) Put(ctx context.Context, key cache.EntryKey, data []byte, ttl cache.TTL) error
- func (b *Backend) Read(ctx context.Context, key cache.EntryKey, data bool) (*cacheatomic.Record, time.Time, error)
- func (b *Backend) Start(ctx context.Context) error
- func (b *Backend) Sweep(ctx context.Context, limit int) (PruneResult, error)
- type Config
- type PruneResult
Constants ¶
const CreateCache migrate.ID = "000001_create_cache"
const MaxPrune = cacheatomic.MaxPrune
const MigrationOrigin migrate.Origin = "foundry.cache"
Variables ¶
This section is empty.
Functions ¶
func Migrations ¶
func Migrations() []migrate.Definition
Migrations are applied explicitly by the ordinary runner in Config.Schema. Table rows are isolated by complete application/environment/tenant addresses.
Types ¶
type Backend ¶
type Backend struct {
*cacheatomic.Backend
// contains filtered or unexported fields
}
Backend borrows its database. Reads are single statements on the primary with no lock or explicit transaction. Put, Add and Forget are single atomic statements; Increment and Expire lock only their own row. Start optionally runs the owned pruner; Close stops it and waits for admitted operations. Operations work without Start, but no automatic pruning runs then.
func (*Backend) Access ¶
func (b *Backend) Access(ctx context.Context, key cache.EntryKey, mode cacheatomic.Mode, change cacheatomic.Change) error
Access runs one change while holding the key's row lock (SELECT ... FOR UPDATE). An absent key is inserted with ON CONFLICT DO NOTHING; losing that race re-reads and locks the concurrent row. The authority time is read after the lock. No schema-wide lock is taken.
func (*Backend) Add ¶
func (b *Backend) Add(ctx context.Context, key cache.EntryKey, data []byte, ttl cache.TTL) (bool, error)
Add inserts, or replaces only an expired, over-bound or mismatched row, in one statement; the conflict condition is evaluated on the locked row.
func (*Backend) Close ¶
Close rejects new operations, stops the pruner and waits for admitted work. It never closes the borrowed database. A canceled caller only stops waiting.
func (*Backend) Done ¶
func (b *Backend) Done() <-chan struct{}
Done closes after shutdown drains admitted operations and the background pruner.
func (*Backend) FlushNamespace ¶
FlushNamespace deletes every row whose address belongs to namespace in one statement. It is not a fence against writes that start afterwards.
func (*Backend) Forget ¶
Forget deletes the row in one statement and reports whether it was a live, usable entry. Unusable rows are removed but reported as absent.
func (*Backend) FoundryAdapter ¶
func (*Backend) FoundryAdapter(frameworkadapter.Seal)
FoundryAdapter marks the backend as framework-owned adapter I/O.
func (*Backend) Inspect ¶
func (b *Backend) Inspect(ctx context.Context, key cache.EntryKey, inspect cacheatomic.Inspection) (bool, error)
Inspect locks only this row, reads the authority time after the lock and changes expiry without selecting the payload. Unusable rows are absent.
func (*Backend) Put ¶
Put replaces one row in a single atomic statement with the expiry computed by the database (or injected) clock at write time.
func (*Backend) Read ¶
func (b *Backend) Read(ctx context.Context, key cache.EntryKey, data bool) (*cacheatomic.Record, time.Time, error)
Read is one statement on the primary: no lock and no explicit transaction. Over-bound or mismatched rows read as absent.
func (*Backend) Start ¶
Start performs no I/O (the table may not be migrated yet at boot): when PruneInterval is positive it starts the owned background pruner, whose failures are logged and retried at the next interval. Repeated starts are no-ops. The first write seeds the usage estimate with one bounded count.
type Config ¶
type Config struct {
Schema string
MaxEntries int
MaxBytes int64
MaxValueBytes int
// Clock, when set, replaces PostgreSQL's clock_timestamp() for expiry. Leave
// it nil in production so every application server shares the database's
// time; tests may inject a deterministic clock.
Clock clock.Clock
// PruneInterval runs automatic deletion of expired rows while the backend is
// started. Zero disables it; otherwise 1s to 24h.
PruneInterval time.Duration
// Logger optionally receives redacted automatic-prune failures.
Logger *slog.Logger
}
Config bounds one shared table. Rows count until removed, but a write never fails because of expired rows: at capacity the backend first deletes up to MaxPrune expired rows, then rejects only if still full. Usage is an estimate maintained by this process and recounted by every prune pass, so processes sharing a schema can briefly overshoot between passes. Processes sharing a schema must use the same bounds and the same Foundry version.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns bounded defaults using the public schema and database authority time.
type PruneResult ¶
type PruneResult = cacheatomic.PruneResult
PruneResult reports one bounded prune pass and the recounted usage.