state

package
v0.0.0-...-21b989b Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package state is the per-site key-value store backing the sandbox's `kv.*` API. The Store interface is deliberately narrow — Load and Save over a Snapshot — so we can swap implementations later (cache layer, bbolt, SQLite) without touching the sandbox or agent surfaces.

The default implementation is S3Store, which loads and saves the whole per-site blob on every request with ETag-based optimistic concurrency. Slow by web standards (~30-100 ms per dynamic request), simple by everything-else standards.

Index

Constants

This section is empty.

Variables

View Source
var ErrConflict = errors.New("state: cas conflict")

ErrConflict is returned by Save when the underlying storage rejects the write because the ETag precondition failed. Callers should reload and retry the handler.

Functions

This section is empty.

Types

type Memory

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

Memory is an in-memory Store useful for tests and benchmarks. It enforces the same ETag CAS semantics as S3Store so handler-retry-on-conflict logic can be exercised without S3.

func NewMemory

func NewMemory() *Memory

func (*Memory) Load

func (m *Memory) Load(_ context.Context, slug string) (*Snapshot, error)

func (*Memory) Save

func (m *Memory) Save(_ context.Context, slug string, snap *Snapshot) error

type S3Store

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

S3Store persists per-site KV state as one JSON blob per slug at `{slug}/_state/data.json`, using ETag-based optimistic concurrency. Every Load is one S3 GET, every Save is one S3 PUT; no caches, no goroutines, no background work.

func NewS3

func NewS3(client *s3.Client, bucket string) *S3Store

func (*S3Store) Load

func (s *S3Store) Load(ctx context.Context, slug string) (*Snapshot, error)

func (*S3Store) Save

func (s *S3Store) Save(ctx context.Context, slug string, snap *Snapshot) error

type Snapshot

type Snapshot struct {
	Data  map[string]any
	ETag  string
	Dirty bool
}

Snapshot is a per-request working copy of a slug's KV state. Handlers mutate Data in memory; if Dirty is true at the end, the host calls Store.Save to persist it. ETag is the precondition for the next save; an empty ETag means "no version exists yet" and Save will use If-None-Match: * to avoid trampling a concurrent creator.

func NewSnapshot

func NewSnapshot() *Snapshot

NewSnapshot returns an empty Snapshot suitable for first-write scenarios.

type Store

type Store interface {
	// Load returns the current Snapshot for slug. A missing slug returns an
	// empty Snapshot with an empty ETag — not an error.
	Load(ctx context.Context, slug string) (*Snapshot, error)

	// Save writes snap.Data back as the new state for slug, conditional on
	// snap.ETag matching the current stored version. Returns ErrConflict on
	// precondition failure; snap.ETag is updated to the new version on success.
	Save(ctx context.Context, slug string, snap *Snapshot) error
}

Store is the per-site state backend. Implementations must be safe for concurrent use across slugs and serialize concurrent writes to the same slug via the ETag precondition surfaced through Snapshot.

Jump to

Keyboard shortcuts

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