plug

package
v0.33.0 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 9 Imported by: 0

README

plug

import "github.com/kitsunium/sdk/framework/internal/kit/plug"

Package plug is where kit's opt-in subsystems plug in: the HTTP engine, the frontends' file server and the process sampler of the runtime graph (framework/kit/server), the Studio's event stream and its profiler (framework/kit/studio), the stores and the databases (framework/kit/store), the queues (framework/kit/queue). kit reads what they registered through the hooks declared here, and imports none of the SDK packages behind them: a product that does not import a subsystem neither links nor initialises its packages.

It is also the contract between kit's core and the subsystems ADR 0179 takes out of it, as database/sql/driver is between database/sql and a driver: the store subsystem's engine over documents, its siblings, kit's scope on a database and its migrations (Stores), which framework/kit/store sets; the refusals an engine says in kit's terms (Refusal); what kit's transactions offer an engine that takes part in them (Transaction); and the queue subsystem's brokers and their consumer (Queues), which framework/kit/queue sets.

The package imports the standard library and the framework's model only, so that kit and every subsystem can import it.

Index

Constants

const LabelLoop string = "kit_loop"

LabelLoop is the pprof label naming the loop a goroutine belongs to.

const LabelNode string = "kit_node"

LabelNode is the pprof label naming the node a goroutine works for.

const RefusalClosed Refusal = 13

RefusalClosed is a call on a closed engine.

const RefusalExists Refusal = 2

RefusalExists is a document already under the key an insertion names.

const RefusalIndexBroken Refusal = 8

RefusalIndexBroken is stored documents that break a unique index.

const RefusalIndexNotUnique Refusal = 7

RefusalIndexNotUnique is a lookup on an index that is not unique.

const RefusalIndexUnknown Refusal = 6

RefusalIndexUnknown is an index the store does not declare.

const RefusalKeyChanged Refusal = 5

RefusalKeyChanged is an update that changes the document's key.

const RefusalKeyEmpty Refusal = 4

RefusalKeyEmpty is a document whose key is empty.

const RefusalKeyTooLong Refusal = 18

RefusalKeyTooLong is a key longer than a database's key columns hold; its "max" field says how long they hold.

const RefusalLoad Refusal = 12

RefusalLoad is a store that could not be loaded; its "problem" field says why.

const RefusalNone Refusal = 0

RefusalNone is no refusal kit words.

const RefusalNotFound Refusal = 1

RefusalNotFound is no document under the key, or under the index's key.

const RefusalNotTrashed Refusal = 17

RefusalNotTrashed is no record in the trash under the key.

const RefusalOutOfOrder Refusal = 22

RefusalOutOfOrder is a migration older than one already applied; its "applied" field names the newer.

const RefusalPersist Refusal = 11

RefusalPersist is a write the store could not keep.

const RefusalStatement Refusal = 19

RefusalStatement is a statement the database did not complete.

const RefusalTxClosed Refusal = 20

RefusalTxClosed is a call with the context of a transaction that ended.

const RefusalTxFailed Refusal = 21

RefusalTxFailed is a transaction or a savepoint the database would not open, commit or roll back.

const RefusalUnconfirmed Refusal = 14

RefusalUnconfirmed is a write that stands but whose survival across a power loss is in doubt.

const RefusalUndecodable Refusal = 9

RefusalUndecodable is a record that does not decode into its type.

const RefusalUnencodable Refusal = 10

RefusalUnencodable is an entity that does not encode.

const RefusalUniqueTaken Refusal = 3

RefusalUniqueTaken is another document under a unique index's key.

const RefusalVersionsNotKept Refusal = 15

RefusalVersionsNotKept is a call on the versions of a store that keeps none.

const RefusalVersionsRewrite Refusal = 16

RefusalVersionsRewrite is a rewrite of versions that adds or renumbers one.

const WriteInsert WriteMode = 1

WriteInsert expects nothing under the key, and is refused otherwise.

const WriteReplace WriteMode = 2

WriteReplace expects a document under the key, and is refused otherwise: never a resurrection.

const WriteUpsert WriteMode = 0

WriteUpsert writes whatever the key holds: a creation or a replacement.

Variables

var NewHTTPServer atomic.Pointer[func(cfg HTTPConfig) HTTPServer]

NewHTTPServer builds the HTTP engine an app in the server profile serves on; nil until framework/kit/server is imported.

var NewStaticFiles atomic.Pointer[func(fsys fs.FS, csp string) (http.Handler, error)]

NewStaticFiles builds the file server of a frontend's tree; nil until framework/kit/server is imported.

var OpenEventStream atomic.Pointer[func(w http.ResponseWriter, r *http.Request) (EventStream, error)]

OpenEventStream opens a Server-Sent Events stream on w; nil until framework/kit/studio is imported.

var Queues atomic.Pointer[QueueDriverConfig]

Queues is the queue subsystem: the brokers kit's consumers' queues run on and the migration of a queue's table on a database; nil until framework/kit/queue is imported. A product that declares a topic, a subscription, a watch, a queued command or a mailer whose outbox is on a database without it is refused at the start (ADR 0179 §6).

var SampleProcess atomic.Pointer[func() *model.Process]

SampleProcess samples the running process — its heap, goroutines, collections and CPU time — for the runtime graph a serving app answers; nil until framework/kit/server is imported, and the graph then carries no process (ADR 0172).

var Stores atomic.Pointer[StoreDriverConfig]

Stores is the store subsystem: the engines kit's stores run on, kit's scope on a database and the migrations of kit's tables; nil until framework/kit/store is imported. A product that declares a store or a database without it is refused at the start (ADR 0179 §6).

var StudioProfiler atomic.Pointer[ProfilerConfig]

StudioProfiler is the Studio's profiler; nil until framework/kit/studio is imported.

func Refuse

func Refuse(kind Refusal, err error) error

Refuse is err as a refusal of kind.

func Refused

func Refused(err error, kind Refusal) bool

Refused reports whether err, or an error it wraps, is a refusal of kind.

type Broker

Broker is one queue as kit's core uses it: a publication, the consumer that delivers it, and its dead letters. It grows by the sibling below.

type Broker interface {
	// Consume delivers the queue's messages to cfg's handler until ctx ends
	// or the queue's storage fails.
	Consume(ctx context.Context, cfg ConsumeConfig) error
	// DeadLetters are up to maxLetters of the queue's dead letters, oldest
	// first.
	DeadLetters(ctx context.Context, maxLetters int) ([]DeadLetterValue, error)
	// Publish puts payload in the queue: in the transaction ctx carries for
	// its database, when it lives on one.
	Publish(ctx context.Context, payload []byte) error
}

func (Broker) Consume
func (Broker) Consume(ctx context.Context, cfg ConsumeConfig) error

Consume delivers the queue's messages to cfg's handler until ctx ends or the queue's storage fails.

func (Broker) DeadLetters
func (Broker) DeadLetters(ctx context.Context, maxLetters int) ([]DeadLetterValue, error)

DeadLetters are up to maxLetters of the queue's dead letters, oldest first.

func (Broker) Publish
func (Broker) Publish(ctx context.Context, payload []byte) error

Publish puts payload in the queue: in the transaction ctx carries for its database, when it lives on one.

type Checker

Checker is a Database that says whether it answers. A sibling of Database.

type Checker interface {
	// Check asks the database whether it answers, within its check timeout.
	Check(ctx context.Context) error
}

func (Checker) Check
func (Checker) Check(ctx context.Context) error

Check asks the database whether it answers, within its check timeout.

type Clock

Clock is the app's clock as a queue stamps and waits on it: kit's core hands the one its app runs on, a test's manual clock included.

type Clock interface {
	// After is a channel that receives the clock's instant once d passed.
	After(d time.Duration) <-chan time.Time
	// NewTicker is a ticker that fires every d.
	NewTicker(d time.Duration) Ticker
	// NewTimer is a timer that fires once d passed.
	NewTimer(d time.Duration) Timer
	// Now is the clock's instant.
	Now() time.Time
	// Since is how long ago t was, on the clock.
	Since(t time.Time) time.Duration
	// Sleep waits until d passed.
	Sleep(d time.Duration)
}

func (Clock) After
func (Clock) After(d time.Duration) <-chan time.Time

After is a channel that receives the clock's instant once d passed.

func (Clock) NewTicker
func (Clock) NewTicker(d time.Duration) Ticker

NewTicker is a ticker that fires every d.

func (Clock) NewTimer
func (Clock) NewTimer(d time.Duration) Timer

NewTimer is a timer that fires once d passed.

func (Clock) Now
func (Clock) Now() time.Time

Now is the clock's instant.

func (Clock) Since
func (Clock) Since(t time.Time) time.Duration

Since is how long ago t was, on the clock.

func (Clock) Sleep
func (Clock) Sleep(d time.Duration)

Sleep waits until d passed.

type ConsumeConfig

ConsumeConfig is how a queue's consumer runs: its handler, how long it waits idle, how many messages it handles at once and takes at a time.

type ConsumeConfig struct {
	// Handler handles one delivery: nil acknowledges it, an error has it
	// retried or, through DoNotRetry, dead-lettered at once. Every handler
	// kit runs tolerates a redelivery.
	Handler      func(ctx context.Context, d DeliveryValue) error
	// PollInterval bounds an idle wait.
	PollInterval time.Duration
	// Parallelism is how many deliveries are handled at once.
	Parallelism  int
	// BatchSize is how many messages the consumer takes at a time.
	BatchSize    int
}

type Database

Database is kit's scope on one database (ADR 0179 §2): the transactions kit.Transact opens on it, their savepoints, and the functions held until their end. The core knows a database only through it; the store package implements it over the SDK's sql. It grows by the siblings below.

type Database interface {
	// Defer holds fn until the transaction ctx carries for the database
	// commits, and reports true; outside one it holds nothing and reports
	// false.
	Defer(ctx context.Context, fn func()) bool
	// InTransaction reports whether ctx carries a transaction of this
	// database.
	InTransaction(ctx context.Context) bool
	// OnAbort holds fn until the work of the scope ctx carries for the
	// database is undone, and reports true; outside one it holds nothing
	// and reports false.
	OnAbort(ctx context.Context, fn func(ctx context.Context)) bool
	// Transact runs fn in a transaction of the database, or in a savepoint
	// of the one ctx carries for it: nil commits or releases, an error
	// rolls back.
	Transact(ctx context.Context, fn func(ctx context.Context) error) error
}

func (Database) Defer
func (Database) Defer(ctx context.Context, fn func()) bool

Defer holds fn until the transaction ctx carries for the database commits, and reports true; outside one it holds nothing and reports false.

func (Database) InTransaction
func (Database) InTransaction(ctx context.Context) bool

InTransaction reports whether ctx carries a transaction of this database.

func (Database) OnAbort
func (Database) OnAbort(ctx context.Context, fn func(ctx context.Context)) bool

OnAbort holds fn until the work of the scope ctx carries for the database is undone, and reports true; outside one it holds nothing and reports false.

func (Database) Transact
func (Database) Transact(ctx context.Context, fn func(ctx context.Context) error) error

Transact runs fn in a transaction of the database, or in a savepoint of the one ctx carries for it: nil commits or releases, an error rolls back.

type DatabaseConfig

DatabaseConfig is one database a product declares, as kit opened it: its pool, its dialect, its tuning and the timeout of each call.

type DatabaseConfig struct {
	// Name is the database's, as the product declared it.
	Name         string
	// DB is the pool kit.Engine opened.
	DB           *sql.DB
	// Dialect is the engine's SQL dialect: "postgres", "mysql" or
	// "sqlite".
	Dialect      string
	// Timeout bounds each call kit makes on the database.
	Timeout      time.Duration
	// MaxOpen and MaxIdle bound the pool's connections.
	MaxOpen      int
	// MaxOpen and MaxIdle bound the pool's connections.
	MaxIdle      int
	// MaxLifetime and MaxIdleTime bound a connection's life.
	MaxLifetime  time.Duration
	// MaxLifetime and MaxIdleTime bound a connection's life.
	MaxIdleTime  time.Duration
	// CheckTimeout bounds a check of the database.
	CheckTimeout time.Duration
}

type DeadLetterValue

DeadLetterValue is a message its queue gave up on: when, why, and how many times it was delivered.

type DeadLetterValue struct {
	// FailedAt is when its last attempt failed.
	FailedAt   time.Time
	// Reason is the failure's identifier.
	Reason     string
	// Cause is the failure's public text, "" for none.
	Cause      string
	// Message is the message, unmodified.
	Message    MessageValue
	// Code is the failure's error code, 0 for none.
	Code       uint32
	// Deliveries counts its deliveries.
	Deliveries int
}

type DeliveryValue

DeliveryValue is one delivery of a message: the message, and how many times it has been delivered, this one included.

type DeliveryValue struct {
	// Message is what is delivered.
	Message    MessageValue
	// Deliveries counts the deliveries, this one included.
	Deliveries int
}

type DocumentSink

DocumentSink is a store's documents on the database a data copy writes. A sibling of Documents.

type DocumentSink interface {
	// InsertRaw writes a document of a store that keeps no versions, as it
	// rests.
	InsertRaw(ctx context.Context, raw json.RawMessage) error
	// PutDocument writes the document key with its versions and its trash
	// as they are given.
	PutDocument(ctx context.Context, key string, versions []VersionValue, trashedAt time.Time) error
}

func (DocumentSink) InsertRaw
func (DocumentSink) InsertRaw(ctx context.Context, raw json.RawMessage) error

InsertRaw writes a document of a store that keeps no versions, as it rests.

func (DocumentSink) PutDocument
func (DocumentSink) PutDocument(ctx context.Context, key string, versions []VersionValue, trashedAt time.Time) error

PutDocument writes the document key with its versions and its trash as they are given.

type DocumentSource

DocumentSource is an engine that says the document store it runs on: itself, or the one what it wraps runs on. A data copy reads and writes a store through it (ADR 0178 C7). A sibling of StoreEngine.

type DocumentSource interface {
	// Documents is the document store the engine runs on, and whether there
	// is one.
	Documents() (Documents, bool)
}

func (DocumentSource) Documents
func (DocumentSource) Documents() (Documents, bool)

Documents is the document store the engine runs on, and whether there is one.

type DocumentValue

DocumentValue is a record as a store's engine holds it (ADR 0179 §2): its JSON as it rests, byte for byte what kit encodes, and the entity once decoded, kept beside it so that a read, an index or a privacy walk does not decode it twice.

type DocumentValue struct {
	// JSON is the record as it rests.
	JSON  json.RawMessage
	// Value is the entity decoded from JSON, nil until something decoded it;
	// the store's typed facade asserts it to its type.
	Value any
}

type Documents

Documents is a store's documents as they rest, as a data copy reads them.

type Documents interface {
	// Current is the document key as the store keeps it.
	Current(ctx context.Context, key string) (json.RawMessage, error)
	// KeepsVersions reports whether the store keeps versions.
	KeepsVersions() bool
	// KeyList yields every key the store holds, in key order.
	KeyList(ctx context.Context) iter.Seq2[string, error]
	// TombstoneList is the trash, in key order: none when the store keeps
	// no versions.
	TombstoneList(ctx context.Context) ([]TombstoneValue, error)
	// VersionList is the versions of the document key, newest first.
	VersionList(ctx context.Context, key string) ([]VersionValue, error)
}

func (Documents) Current
func (Documents) Current(ctx context.Context, key string) (json.RawMessage, error)

Current is the document key as the store keeps it.

func (Documents) KeepsVersions
func (Documents) KeepsVersions() bool

KeepsVersions reports whether the store keeps versions.

func (Documents) KeyList
func (Documents) KeyList(ctx context.Context) iter.Seq2[string, error]

KeyList yields every key the store holds, in key order.

func (Documents) TombstoneList
func (Documents) TombstoneList(ctx context.Context) ([]TombstoneValue, error)

TombstoneList is the trash, in key order: none when the store keeps no versions.

func (Documents) VersionList
func (Documents) VersionList(ctx context.Context, key string) ([]VersionValue, error)

VersionList is the versions of the document key, newest first.

type EntrySource

EntrySource is an engine that lists its records as they rest with their keys: what a sealing store reads its records by. A sibling of StoreEngine.

type EntrySource interface {
	// KeyedEntries returns up to limit records as they rest, in key order.
	KeyedEntries(ctx context.Context, limit int) ([]EntryValue, error)
}

func (EntrySource) KeyedEntries
func (EntrySource) KeyedEntries(ctx context.Context, limit int) ([]EntryValue, error)

KeyedEntries returns up to limit records as they rest, in key order.

type EntryValue

EntryValue is a record as it rests, with its key: what an engine lists for a reader that cannot key a record itself.

type EntryValue struct {
	// Key is the record's key.
	Key  string
	// JSON is the record as it rests.
	JSON json.RawMessage
}

type EventStream

EventStream is one Server-Sent Events stream: the Studio's live events.

type EventStream interface {
	// Close ends the stream.
	Close() error
	// Done is closed when the client left.
	Done() <-chan struct{}
	// Send writes one event's data.
	Send(data string) error
}

func (EventStream) Close
func (EventStream) Close() error

Close ends the stream.

func (EventStream) Done
func (EventStream) Done() <-chan struct{}

Done is closed when the client left.

func (EventStream) Send
func (EventStream) Send(data string) error

Send writes one event's data.

type Executor

Executor is what a migration's step runs its statements on: the transaction its migration runs in.

type Executor interface {
	// ExecContext runs a statement that returns no rows.
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
	// QueryContext runs a query that returns rows.
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
	// QueryRowContext runs a query that returns at most one row.
	QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
}

func (Executor) ExecContext
func (Executor) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)

ExecContext runs a statement that returns no rows.

func (Executor) QueryContext
func (Executor) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)

QueryContext runs a query that returns rows.

func (Executor) QueryRowContext
func (Executor) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row

QueryRowContext runs a query that returns at most one row.

type Folder

Folder is an engine that keeps what its writes left beside its data, and can fold it in now. A sibling of StoreEngine.

type Folder interface {
	// Fold rewrites the store's data with only what it holds now.
	Fold(ctx context.Context) error
}

func (Folder) Fold
func (Folder) Fold(ctx context.Context) error

Fold rewrites the store's data with only what it holds now.

type HTTPConfig

HTTPConfig is what kit asks of the HTTP engine: where to listen, its one socket, its bounds, and the handler.

type HTTPConfig struct {
	// Addr is where to listen, "host:port".
	Addr           string
	// Shards is how many sockets the engine opens on Addr.
	Shards         int
	// ReadHeader, Read, Write and Idle bound a request's phases.
	ReadHeader     time.Duration
	// ReadHeader, Read, Write and Idle bound a request's phases.
	Read           time.Duration
	// ReadHeader, Read, Write and Idle bound a request's phases.
	Write          time.Duration
	// ReadHeader, Read, Write and Idle bound a request's phases.
	Idle           time.Duration
	// MaxHeaderBytes bounds a request's header.
	MaxHeaderBytes int
	// Handler answers every request.
	Handler        http.Handler
}

type HTTPServer

HTTPServer is the HTTP engine kit starts, reads and stops.

type HTTPServer interface {
	// Shutdown drains the engine within ctx.
	Shutdown(ctx context.Context) error
	// Start binds the address and serves, returning once bound.
	Start(ctx context.Context) error
	// State says what the engine binds and serves.
	State() HTTPState
}

func (HTTPServer) Shutdown
func (HTTPServer) Shutdown(ctx context.Context) error

Shutdown drains the engine within ctx.

func (HTTPServer) Start
func (HTTPServer) Start(ctx context.Context) error

Start binds the address and serves, returning once bound.

func (HTTPServer) State
func (HTTPServer) State() HTTPState

State says what the engine binds and serves.

type HTTPState

HTTPState is what the HTTP engine says of itself once it runs: the address it bound, and its connections.

type HTTPState struct {
	// Addr is the address the engine bound, "" before it did.
	Addr      string
	// Listeners is how many sockets it listens on.
	Listeners int
	// Active are the connections being served, Total those accepted since
	// the start, Rejected those refused.
	Active    int64
	Total     uint64
	Rejected  uint64
}

type HandleProvider

HandleProvider is a value of a subsystem that hands one of the SDK's own handles on: the value dst points at set, and true; false for a handle it has none of. It serves the mailer's spool, still in kit's core, which takes the SDK's types — a Database's transaction manager as the spool's Deferrer, a queue's broker (Broker) as its outbox — until the mailers leave the core (ADR 0179, step 6), and the core never names the type it asks for. A sibling of Database and of Broker.

type HandleProvider interface {
	// Handle sets what dst points at to the SDK's handle of its type.
	Handle(dst any) bool
}

func (HandleProvider) Handle
func (HandleProvider) Handle(dst any) bool

Handle sets what dst points at to the SDK's handle of its type.

type IndexSpec

IndexSpec declares one secondary index of a store, over documents: the product's index function on its type, wrapped once at the declaration.

type IndexSpec struct {
	// Name reads the index, and names it in a refusal.
	Name   string
	// Unique refuses a write that would file two documents under one key.
	Unique bool
	// Keys are a document's keys in the index; an empty key is not indexed.
	Keys   func(d DocumentValue) []string
}

type Keyser

Keyser is an engine that lists the keys of its documents, in key order, above after, without reading a document. A sibling of StoreEngine.

type Keyser interface {
	// Keys yields the keys above after, in order, then its failure if any.
	Keys(ctx context.Context, after string) iter.Seq2[string, error]
}

func (Keyser) Keys
func (Keyser) Keys(ctx context.Context, after string) iter.Seq2[string, error]

Keys yields the keys above after, in order, then its failure if any.

type LiveMessageValue

LiveMessageValue is a message waiting in its queue, as it lies: when it is next visible, how many times it was delivered, and whether a consumer holds it.

type LiveMessageValue struct {
	// VisibleAt is when the message is next delivered.
	VisibleAt  time.Time
	// Message is the message.
	Message    MessageValue
	// Deliveries counts its deliveries so far.
	Deliveries int
	// Leased reports whether a consumer holds it.
	Leased     bool
}

type MessageMover

MessageMover is a Broker whose messages a data copy reads and writes as they lie, without a lease, with their counts and their instants. A sibling of Broker.

type MessageMover interface {
	// Messages are up to maxMessages live messages after the identifier
	// after, "" for the first, in their queue's order.
	Messages(ctx context.Context, after string, maxMessages int) ([]LiveMessageValue, error)
	// PutDeadLetter writes dead, with its cause, under an identifier of the
	// queue's own, and returns it.
	PutDeadLetter(ctx context.Context, dead DeadLetterValue) (string, error)
	// PutMessage writes live under an identifier of the queue's own, and
	// returns it.
	PutMessage(ctx context.Context, live LiveMessageValue) (string, error)
}

func (MessageMover) Messages
func (MessageMover) Messages(ctx context.Context, after string, maxMessages int) ([]LiveMessageValue, error)

Messages are up to maxMessages live messages after the identifier after, "" for the first, in their queue's order.

func (MessageMover) PutDeadLetter
func (MessageMover) PutDeadLetter(ctx context.Context, dead DeadLetterValue) (string, error)

PutDeadLetter writes dead, with its cause, under an identifier of the queue's own, and returns it.

func (MessageMover) PutMessage
func (MessageMover) PutMessage(ctx context.Context, live LiveMessageValue) (string, error)

PutMessage writes live under an identifier of the queue's own, and returns it.

type MessageValue

MessageValue is one message of a queue: its identifier, its payload as kit encoded it, and when it was published.

type MessageValue struct {
	// EnqueuedAt is when the message was published.
	EnqueuedAt time.Time
	// ID identifies the message in its queue.
	ID         string
	// Payload is the message as kit encoded it.
	Payload    []byte
}

type MigrationValue

MigrationValue is one versioned change of a database's schema and its reversal, as kit's migrations are written: the SDK's own, on the standard library's types.

type MigrationValue struct {
	// Version orders the migration in its set: non-zero and unique.
	Version uint64
	// Name labels it in the version table.
	Name    string
	// Up applies the change.
	Up      Step
	// Down reverses it.
	Down    Step
}

type Migrator

Migrator is one set of migrations on a database.

type Migrator interface {
	// Down reverses the applied migrations above version, newest first.
	Down(ctx context.Context, version uint64) error
	// Plan is the set's pending migrations, oldest first, applying nothing.
	Plan(ctx context.Context) ([]MigrationValue, error)
	// Up applies every pending migration, in order.
	Up(ctx context.Context) error
}

func (Migrator) Down
func (Migrator) Down(ctx context.Context, version uint64) error

Down reverses the applied migrations above version, newest first.

func (Migrator) Plan
func (Migrator) Plan(ctx context.Context) ([]MigrationValue, error)

Plan is the set's pending migrations, oldest first, applying nothing.

func (Migrator) Up
func (Migrator) Up(ctx context.Context) error

Up applies every pending migration, in order.

type MigratorProvider

MigratorProvider is a Database that runs a set of migrations under a version table of its own, and so a lock of its own. A sibling of Database.

type MigratorProvider interface {
	// Migrator is the set ms, under the version table table.
	Migrator(table string, ms []MigrationValue) (Migrator, error)
}

func (MigratorProvider) Migrator
func (MigratorProvider) Migrator(table string, ms []MigrationValue) (Migrator, error)

Migrator is the set ms, under the version table table.

type ProfilerConfig

ProfilerConfig is the Studio's profiler: the live heap folded onto the graph's nodes, and every goroutine grouped.

type ProfilerConfig struct {
	// Heap folds the live heap onto g's nodes; source says where a function
	// of a module lies, nil when it knows none.
	Heap       func(g *model.Graph, source SourceFunc) (*model.Profile, error)
	// Goroutines groups every goroutine of the process, read at at.
	Goroutines func(at time.Time) (*model.Goroutines, error)
}

type QueueConfig

QueueConfig is what kit asks of one queue: where it lies, its policy, the app's clock, and for a mailer's outbox the sealing of what it keeps.

type QueueConfig struct {
	// Name names the queue's node in a refusal: the consumer's or the
	// mailer's node ID.
	Name       string
	// Dir is the directory a file queue lies in; with no Database and no
	// Dir, the queue is in memory.
	Dir        string
	// Database keeps the queue, nil when Dir or memory does: a scope the
	// store subsystem's Database opened, whose transaction a publication in
	// it joins.
	Database   Database
	// Table is the queue's table on Database.
	Table      string
	// Policy is how the queue leases, retries and bounds its messages.
	Policy     QueuePolicyValue
	// Clock is the app's clock, which the queue stamps and waits on.
	Clock      Clock
	// Seal, when set, seals every payload on its way in — a mail's, in a
	// mailer's outbox on a database —, and Unseal opens one on its way out;
	// MaxPayload bounds a payload before it is sealed.
	Seal       func(ctx context.Context, payload []byte) ([]byte, error)
	// Unseal is the payload a box holds, the box as it lies when it does
	// not open.
	Unseal     func(ctx context.Context, box []byte) []byte
	// MaxPayload bounds a payload Seal seals.
	MaxPayload int
	// Wrap, when a test sets it, stands in front of the queue the subsystem
	// opens: a func(queue.Broker) queue.Broker of the SDK's queue, which
	// kit's core does not name. Nil in every app a product builds.
	Wrap       any
}

type QueueDriverConfig

QueueDriverConfig is what framework/kit/queue plugs into kit: how a consumer's queue opens, the migration that makes its table on a database, and how a delivery's handler says that no retry can help.

type QueueDriverConfig struct {
	// Open opens one queue, as cfg places it: on a database, in a
	// directory, or in memory.
	Open           func(cfg QueueConfig) (Broker, error)
	// TableMigration is the migration that makes the queue table on a
	// database of the dialect named, at version.
	TableMigration func(dialect string, table string, version uint64) (MigrationValue, error)
	// DoNotRetry is err as a delivery's handler returns it when no retry
	// can help: its queue dead-letters the message at once.
	DoNotRetry     func(err error) error
	// NotRetryable reports whether err, a delivery's handler's, says that no
	// retry can help: what DoNotRetry returned, the product's own included.
	NotRetryable   func(err error) bool
}

type QueuePolicyValue

QueuePolicyValue is how a queue leases, retries and bounds its messages: the SDK's queue policy, in kit's terms.

type QueuePolicyValue struct {
	// VisibilityTimeout is how long a delivery is leased.
	VisibilityTimeout time.Duration
	// RetryDelay is the wait after a message's first failure, doubled after
	// each, up to MaxRetryDelay.
	RetryDelay        time.Duration
	// MaxRetryDelay bounds the wait before a retry; zero leaves it unbound.
	MaxRetryDelay     time.Duration
	// MaxDeliveries is how often a message is delivered before it is
	// dead-lettered.
	MaxDeliveries     int
	// MaxMessageBytes bounds a message; zero is the queue's own bound.
	MaxMessageBytes   int
}

type Refusal

Refusal is a kind of refusal of a store's engine or a database, as kit words it.

type Refusal uint8

type RefusalError

RefusalError is an engine's refusal of one kind: the error it met, and the kind kit words it by.

type RefusalError struct {
	// Err is what the engine met.
	Err  error
	// Kind is how kit words it.
	Kind Refusal
}

func (RefusalError) Error
func (*RefusalError) Error() string

Error is what the engine met's.

func (RefusalError) Unwrap
func (*RefusalError) Unwrap() error

Unwrap is what the engine met.

type Reindexer

Reindexer is an engine on a database that files its index rows again. A sibling of StoreEngine.

type Reindexer interface {
	// Reindex files every record's index rows again.
	Reindex(ctx context.Context) error
}

func (Reindexer) Reindex
func (Reindexer) Reindex(ctx context.Context) error

Reindex files every record's index rows again.

type SourceFunc

SourceFunc says where the function fn, at file:line, lies in the product, nil when it knows none.

type SourceFunc func(file string, line int, fn string) *model.Source

type StampValue

StampValue is what a write says about the version it makes: who made it and which command, kept with the version; and whether it changes the document in place, without a version of its own.

type StampValue struct {
	// Meta is kept with the version the write makes.
	Meta    map[string]string
	// InPlace makes the write change the document without making a version.
	InPlace bool
}

type Step

Step is one direction of a migration, run on ex.

type Step func(ctx context.Context, ex Executor) error

type StoreConfig

StoreConfig is what kit asks of one store's engine: the store, its key and its indexes over documents, where it rests and what it keeps, and how its writes take part in kit's transactions.

type StoreConfig struct {
	// Name is the store's, as a log line and a rollback name it.
	Name        string
	// Key is a document's key: the product's key function on its type,
	// wrapped once at the declaration. It reads the document's Value, which
	// the engine decodes first unless KeyAtRest gives the key.
	Key         func(d DocumentValue) string
	// KeyAtRest, when set, gives the key of a record as it rests, without
	// decoding it; false when it cannot.
	KeyAtRest   func(raw json.RawMessage) (string, bool)
	// Decode is the entity a document's JSON holds, which the engine keeps
	// as the document's Value.
	Decode      func(raw json.RawMessage) (any, error)
	// Indexes are the store's secondary indexes.
	Indexes     []IndexSpec
	// Data is the data directory the store rests in — the SDK's writable
	// file system, which the engine asserts — and Path its snapshot there;
	// a nil Data and a nil Database keep the store in memory.
	Data        fs.FS
	// Path is the store's snapshot in Data.
	Path        string
	// Database keeps the store, nil when the data directory or memory does:
	// a scope the store subsystem's Database opened.
	Database    Database
	// Table is the store's table on Database.
	Table       string
	// IndexKey is the key a table's index keys are hashed under, nil for
	// none: an index key reaches the table as its keyed hash.
	IndexKey    func(index string, key string) []byte
	// Call is the context one call of the engine on Database runs with: on
	// the transaction ctx carries for it, else on the pool, within the
	// database's timeout; done ends it.
	Call        func(ctx context.Context, write bool) (call context.Context, done func(), err error)
	// Versions is how many former versions of each record the engine keeps,
	// none when zero; Clock stamps them.
	Versions    int
	// Clock is the app's clock, which stamps a version.
	Clock       func() time.Time
	// Held reports whether a record's versions are held, and no write may
	// prune them: asked with the write's context, on a database inside its
	// transaction.
	Held        func(ctx context.Context, key string) bool
	// Stamp is what a write under ctx says about the version it makes.
	Stamp       func(ctx context.Context) StampValue
	// Transaction is kit's transaction, which the engine's writes take part
	// in.
	Transaction Transaction
}

type StoreDriverConfig

StoreDriverConfig is what framework/kit/store plugs into kit: how a store's engine opens, how kit opens its scope on a database, and the migration that makes one of kit's tables.

type StoreDriverConfig struct {
	// Open opens the engine of one store, as cfg places it: loaded from the
	// data directory, empty in memory, or on a database.
	Open           func(cfg StoreConfig) (StoreEngine, error)
	// Database opens kit's scope on one database's pool.
	Database       func(cfg DatabaseConfig) (Database, error)
	// TableMigration is the migration that makes the table t on a database
	// of the dialect named, at version.
	TableMigration func(dialect string, t TableSpec, version uint64) (MigrationValue, error)
}

type StoreEngine

StoreEngine is what a store runs on, over documents (ADR 0179 §2): the non-generic engine under Store[T]. Its refusals are kit's (Refusal): the engine translates the SDK's before they reach the core. Every call takes the caller's context, which carries the transaction the call joins. It grows by the sibling interfaces below, never by a method (the SDK's ADR 0039).

type StoreEngine interface {
	// Close releases the engine.
	Close() error
	// Count says how many documents the store holds.
	Count(ctx context.Context) (int, error)
	// Delete removes the document under key.
	Delete(ctx context.Context, key string) error
	// Entries returns up to limit documents as they rest, in key order.
	Entries(ctx context.Context, limit int) ([]json.RawMessage, error)
	// Filter returns the documents keep accepts, in key order.
	Filter(ctx context.Context, keep func(d DocumentValue) bool) ([]DocumentValue, error)
	// Find returns the documents an index files under key, in key order.
	Find(ctx context.Context, index string, key string) ([]DocumentValue, error)
	// Get returns the document under key.
	Get(ctx context.Context, key string) (DocumentValue, error)
	// List returns every document, in key order.
	List(ctx context.Context) ([]DocumentValue, error)
	// Lookup returns the document a unique index files under key.
	Lookup(ctx context.Context, index string, key string) (DocumentValue, error)
	// Update applies fn to the document under key and stores the result,
	// atomically with respect to every other write of the store.
	Update(ctx context.Context, key string, fn func(d *DocumentValue) error) (DocumentValue, error)
	// Watch registers the functions told the key of every document written
	// and deleted, once the write stands.
	Watch(onWrite func(key string), onDelete func(key string))
	// Write stores d as mode says. The document and its index keys are kept
	// together, or neither.
	Write(ctx context.Context, d DocumentValue, mode WriteMode) error
}

func (StoreEngine) Close
func (StoreEngine) Close() error

Close releases the engine.

func (StoreEngine) Count
func (StoreEngine) Count(ctx context.Context) (int, error)

Count says how many documents the store holds.

func (StoreEngine) Delete
func (StoreEngine) Delete(ctx context.Context, key string) error

Delete removes the document under key.

func (StoreEngine) Entries
func (StoreEngine) Entries(ctx context.Context, limit int) ([]json.RawMessage, error)

Entries returns up to limit documents as they rest, in key order.

func (StoreEngine) Filter
func (StoreEngine) Filter(ctx context.Context, keep func(d DocumentValue) bool) ([]DocumentValue, error)

Filter returns the documents keep accepts, in key order.

func (StoreEngine) Find
func (StoreEngine) Find(ctx context.Context, index string, key string) ([]DocumentValue, error)

Find returns the documents an index files under key, in key order.

func (StoreEngine) Get
func (StoreEngine) Get(ctx context.Context, key string) (DocumentValue, error)

Get returns the document under key.

func (StoreEngine) List
func (StoreEngine) List(ctx context.Context) ([]DocumentValue, error)

List returns every document, in key order.

func (StoreEngine) Lookup
func (StoreEngine) Lookup(ctx context.Context, index string, key string) (DocumentValue, error)

Lookup returns the document a unique index files under key.

func (StoreEngine) Update
func (StoreEngine) Update(ctx context.Context, key string, fn func(d *DocumentValue) error) (DocumentValue, error)

Update applies fn to the document under key and stores the result, atomically with respect to every other write of the store.

func (StoreEngine) Watch
func (StoreEngine) Watch(onWrite func(key string), onDelete func(key string))

Watch registers the functions told the key of every document written and deleted, once the write stands.

func (StoreEngine) Write
func (StoreEngine) Write(ctx context.Context, d DocumentValue, mode WriteMode) error

Write stores d as mode says. The document and its index keys are kept together, or neither.

type TableSpec

TableSpec is one of kit's tables on a database, as the store subsystem's migration makes it: a store's, or a store's versions beside the store's table VersionsOf. A consumer's queue's table is the queue subsystem's (QueueDriverConfig's TableMigration).

type TableSpec struct {
	// Name is the table's.
	Name       string
	// VersionsOf is, for a store's versions, the store's table, from which
	// the versions' table is named.
	VersionsOf string
}

type Ticker

Ticker is a ticker of a Clock.

type Ticker interface {
	// C receives the clock's instant at each tick.
	C() <-chan time.Time
	// Reset makes the ticker fire every d.
	Reset(d time.Duration)
	// Stop stops the ticker.
	Stop()
}

func (Ticker) C
func (Ticker) C() <-chan time.Time

C receives the clock's instant at each tick.

func (Ticker) Reset
func (Ticker) Reset(d time.Duration)

Reset makes the ticker fire every d.

func (Ticker) Stop
func (Ticker) Stop()

Stop stops the ticker.

type Timer

Timer is a timer of a Clock.

type Timer interface {
	// C receives the clock's instant when the timer fires.
	C() <-chan time.Time
	// Reset makes the timer fire once d passed, and reports whether it had
	// not fired.
	Reset(d time.Duration) bool
	// Stop stops the timer, and reports whether it had not fired.
	Stop() bool
}

func (Timer) C
func (Timer) C() <-chan time.Time

C receives the clock's instant when the timer fires.

func (Timer) Reset
func (Timer) Reset(d time.Duration) bool

Reset makes the timer fire once d passed, and reports whether it had not fired.

func (Timer) Stop
func (Timer) Stop() bool

Stop stops the timer, and reports whether it had not fired.

type TombstoneValue

TombstoneValue is one record in a store's trash: its key, and when it was trashed.

type TombstoneValue struct {
	// Key is the trashed record's key.
	Key string
	// At is when the record was trashed, in UTC.
	At  time.Time
}

type Transaction

Transaction is kit's transaction as a store's engine takes part in it (ADR 0139, ADR 0178): the core implements it, an engine calls it with its caller's context.

type Transaction interface {
	// AtCommit holds fn until the transaction ctx carries commits, and
	// reports whether it did: false outside one, where the caller runs it
	// now.
	AtCommit(ctx context.Context, fn func()) bool
	// Local reports whether ctx runs in a transaction that holds the data's
	// writer turn: a write in the data directory or in memory then records
	// what it replaces.
	Local(ctx context.Context) bool
	// Retell keeps fn, which announces a write on a database again when the
	// transaction ctx carries rolls it back.
	Retell(ctx context.Context, fn func())
	// Undo keeps restore, which a rollback of the transaction ctx carries
	// runs; nothing outside one. store names the store in a log line.
	Undo(ctx context.Context, store string, restore func(ctx context.Context) error)
}

func (Transaction) AtCommit
func (Transaction) AtCommit(ctx context.Context, fn func()) bool

AtCommit holds fn until the transaction ctx carries commits, and reports whether it did: false outside one, where the caller runs it now.

func (Transaction) Local
func (Transaction) Local(ctx context.Context) bool

Local reports whether ctx runs in a transaction that holds the data's writer turn: a write in the data directory or in memory then records what it replaces.

func (Transaction) Retell
func (Transaction) Retell(ctx context.Context, fn func())

Retell keeps fn, which announces a write on a database again when the transaction ctx carries rolls it back.

func (Transaction) Undo
func (Transaction) Undo(ctx context.Context, store string, restore func(ctx context.Context) error)

Undo keeps restore, which a rollback of the transaction ctx carries runs; nothing outside one. store names the store in a log line.

type Trasher

Trasher is an engine that keeps a trash. A sibling of StoreEngine.

type Trasher interface {
	// Purge empties the trash of the record trashed under key, its versions
	// with it.
	Purge(ctx context.Context, key string) error
	// Tombstones are every record in the trash, in key order.
	Tombstones(ctx context.Context) ([]TombstoneValue, error)
	// Trash moves the record under key to the trash: gone from every read,
	// its index keys freed, its versions kept.
	Trash(ctx context.Context, key string) error
	// Untrash brings the record trashed under key back as it was.
	Untrash(ctx context.Context, key string) error
}

func (Trasher) Purge
func (Trasher) Purge(ctx context.Context, key string) error

Purge empties the trash of the record trashed under key, its versions with it.

func (Trasher) Tombstones
func (Trasher) Tombstones(ctx context.Context) ([]TombstoneValue, error)

Tombstones are every record in the trash, in key order.

func (Trasher) Trash
func (Trasher) Trash(ctx context.Context, key string) error

Trash moves the record under key to the trash: gone from every read, its index keys freed, its versions kept.

func (Trasher) Untrash
func (Trasher) Untrash(ctx context.Context, key string) error

Untrash brings the record trashed under key back as it was.

type VersionKeeper

VersionKeeper is an engine that keeps its records' versions. A sibling of StoreEngine.

type VersionKeeper interface {
	// RewriteVersions rewrites the former versions of the record under key
	// as fn returns them: fn may drop a version or change what one holds,
	// never add or renumber one.
	RewriteVersions(ctx context.Context, key string, fn func(vs []VersionValue) ([]VersionValue, error)) error
	// StoredVersions are the versions of the record under key, newest
	// first, the current one first.
	StoredVersions(ctx context.Context, key string) ([]VersionValue, error)
}

func (VersionKeeper) RewriteVersions
func (VersionKeeper) RewriteVersions(ctx context.Context, key string, fn func(vs []VersionValue) ([]VersionValue, error)) error

RewriteVersions rewrites the former versions of the record under key as fn returns them: fn may drop a version or change what one holds, never add or renumber one.

func (VersionKeeper) StoredVersions
func (VersionKeeper) StoredVersions(ctx context.Context, key string) ([]VersionValue, error)

StoredVersions are the versions of the record under key, newest first, the current one first.

type VersionValue

VersionValue is one version of a record: its number, when the write that made it ran, what that write said about it, and the record as it held it.

type VersionValue struct {
	// Number counts a record's versions from 1.
	Number uint64
	// At is when the write that made the version ran, in UTC.
	At     time.Time
	// Meta is what the write said about it: who made it, which command.
	Meta   map[string]string
	// JSON is the record as the version holds it.
	JSON   json.RawMessage
}

type VersionWeightValue

VersionWeightValue is what a store keeps beyond the records it holds: its former versions and its trash, counted and weighed.

type VersionWeightValue struct {
	// Former is how many former versions the store keeps.
	Former  int
	// Trashed is how many records are in the trash.
	Trashed int
	// Bytes is what the former versions and the trashed records weigh.
	Bytes   int64
}

type VersionWeighter

VersionWeighter is an engine that says what its records' versions weigh. A sibling of StoreEngine.

type VersionWeighter interface {
	// VersionWeight is what the store's versions and trash weigh.
	VersionWeight(ctx context.Context) (VersionWeightValue, error)
}

func (VersionWeighter) VersionWeight
func (VersionWeighter) VersionWeight(ctx context.Context) (VersionWeightValue, error)

VersionWeight is what the store's versions and trash weigh.

type WriteMode

WriteMode says what a write expects to find under the document's key.

type WriteMode int

Generated from docs/api by tools/genindex.

Documentation

Overview

Package plug is where kit's opt-in subsystems plug in: the HTTP engine, the frontends' file server and the process sampler of the runtime graph (framework/kit/server), the Studio's event stream and its profiler (framework/kit/studio), the stores and the databases (framework/kit/store), the queues (framework/kit/queue). kit reads what they registered through the hooks declared here, and imports none of the SDK packages behind them: a product that does not import a subsystem neither links nor initialises its packages.

It is also the contract between kit's core and the subsystems ADR 0179 takes out of it, as database/sql/driver is between database/sql and a driver: the store subsystem's engine over documents, its siblings, kit's scope on a database and its migrations (Stores), which framework/kit/store sets; the refusals an engine says in kit's terms (Refusal); what kit's transactions offer an engine that takes part in them (Transaction); and the queue subsystem's brokers and their consumer (Queues), which framework/kit/queue sets.

The package imports the standard library and the framework's model only, so that kit and every subsystem can import it.

Index

Constants

View Source
const (
	// LabelNode is the pprof label naming the node a goroutine works for.
	LabelNode string = "kit_node"
	// LabelLoop is the pprof label naming the loop a goroutine belongs to.
	LabelLoop string = "kit_loop"
)

Variables

View Source
var (
	// NewHTTPServer builds the HTTP engine an app in the server profile
	// serves on; nil until framework/kit/server is imported.
	NewHTTPServer atomic.Pointer[func(cfg HTTPConfig) HTTPServer]
	// NewStaticFiles builds the file server of a frontend's tree; nil until
	// framework/kit/server is imported.
	NewStaticFiles atomic.Pointer[func(fsys fs.FS, csp string) (http.Handler, error)]
	// SampleProcess samples the running process — its heap, goroutines,
	// collections and CPU time — for the runtime graph a serving app answers;
	// nil until framework/kit/server is imported, and the graph then carries
	// no process (ADR 0172).
	SampleProcess atomic.Pointer[func() *model.Process]
	// OpenEventStream opens a Server-Sent Events stream on w; nil until
	// framework/kit/studio is imported.
	OpenEventStream atomic.Pointer[func(w http.ResponseWriter, r *http.Request) (EventStream, error)]
	// StudioProfiler is the Studio's profiler; nil until framework/kit/studio
	// is imported.
	StudioProfiler atomic.Pointer[ProfilerConfig]
)

Queues is the queue subsystem: the brokers kit's consumers' queues run on and the migration of a queue's table on a database; nil until framework/kit/queue is imported. A product that declares a topic, a subscription, a watch, a queued command or a mailer whose outbox is on a database without it is refused at the start (ADR 0179 §6).

Stores is the store subsystem: the engines kit's stores run on, kit's scope on a database and the migrations of kit's tables; nil until framework/kit/store is imported. A product that declares a store or a database without it is refused at the start (ADR 0179 §6).

Functions

func Refuse added in v0.32.0

func Refuse(kind Refusal, err error) error

Refuse is err as a refusal of kind.

func Refused added in v0.32.0

func Refused(err error, kind Refusal) bool

Refused reports whether err, or an error it wraps, is a refusal of kind.

Types

type Broker added in v0.33.0

type Broker interface {
	// Publish puts payload in the queue: in the transaction ctx carries for
	// its database, when it lives on one.
	Publish(ctx context.Context, payload []byte) error
	// Consume delivers the queue's messages to cfg's handler until ctx ends
	// or the queue's storage fails.
	Consume(ctx context.Context, cfg ConsumeConfig) error
	// DeadLetters are up to maxLetters of the queue's dead letters, oldest
	// first.
	DeadLetters(ctx context.Context, maxLetters int) ([]DeadLetterValue, error)
}

Broker is one queue as kit's core uses it: a publication, the consumer that delivers it, and its dead letters. It grows by the sibling below.

type Checker added in v0.32.0

type Checker interface {
	// Check asks the database whether it answers, within its check timeout.
	Check(ctx context.Context) error
}

Checker is a Database that says whether it answers. A sibling of Database.

type Clock added in v0.33.0

type Clock interface {
	// Now is the clock's instant.
	Now() time.Time
	// Since is how long ago t was, on the clock.
	Since(t time.Time) time.Duration
	// After is a channel that receives the clock's instant once d passed.
	After(d time.Duration) <-chan time.Time
	// NewTimer is a timer that fires once d passed.
	NewTimer(d time.Duration) Timer
	// NewTicker is a ticker that fires every d.
	NewTicker(d time.Duration) Ticker
	// Sleep waits until d passed.
	Sleep(d time.Duration)
}

Clock is the app's clock as a queue stamps and waits on it: kit's core hands the one its app runs on, a test's manual clock included.

type ConsumeConfig added in v0.33.0

type ConsumeConfig struct {
	// Handler handles one delivery: nil acknowledges it, an error has it
	// retried or, through DoNotRetry, dead-lettered at once. Every handler
	// kit runs tolerates a redelivery.
	Handler func(ctx context.Context, d DeliveryValue) error
	// PollInterval bounds an idle wait.
	PollInterval time.Duration
	// Parallelism is how many deliveries are handled at once.
	Parallelism int
	// BatchSize is how many messages the consumer takes at a time.
	BatchSize int
}

ConsumeConfig is how a queue's consumer runs: its handler, how long it waits idle, how many messages it handles at once and takes at a time.

type Database added in v0.31.0

type Database interface {
	// Transact runs fn in a transaction of the database, or in a savepoint
	// of the one ctx carries for it: nil commits or releases, an error
	// rolls back.
	Transact(ctx context.Context, fn func(ctx context.Context) error) error
	// InTransaction reports whether ctx carries a transaction of this
	// database.
	InTransaction(ctx context.Context) bool
	// Defer holds fn until the transaction ctx carries for the database
	// commits, and reports true; outside one it holds nothing and reports
	// false.
	Defer(ctx context.Context, fn func()) bool
	// OnAbort holds fn until the work of the scope ctx carries for the
	// database is undone, and reports true; outside one it holds nothing
	// and reports false.
	OnAbort(ctx context.Context, fn func(ctx context.Context)) bool
}

Database is kit's scope on one database (ADR 0179 §2): the transactions kit.Transact opens on it, their savepoints, and the functions held until their end. The core knows a database only through it; the store package implements it over the SDK's sql. It grows by the siblings below.

type DatabaseConfig added in v0.31.0

type DatabaseConfig struct {
	// Name is the database's, as the product declared it.
	Name string
	// DB is the pool kit.Engine opened.
	DB *sql.DB
	// Dialect is the engine's SQL dialect: "postgres", "mysql" or
	// "sqlite".
	Dialect string
	// Timeout bounds each call kit makes on the database.
	Timeout time.Duration
	// MaxOpen and MaxIdle bound the pool's connections.
	MaxOpen, MaxIdle int
	// MaxLifetime and MaxIdleTime bound a connection's life.
	MaxLifetime, MaxIdleTime time.Duration
	// CheckTimeout bounds a check of the database.
	CheckTimeout time.Duration
}

DatabaseConfig is one database a product declares, as kit opened it: its pool, its dialect, its tuning and the timeout of each call.

type DeadLetterValue added in v0.33.0

type DeadLetterValue struct {
	// FailedAt is when its last attempt failed.
	FailedAt time.Time
	// Reason is the failure's identifier.
	Reason string
	// Cause is the failure's public text, "" for none.
	Cause string
	// Message is the message, unmodified.
	Message MessageValue
	// Code is the failure's error code, 0 for none.
	Code uint32
	// Deliveries counts its deliveries.
	Deliveries int
}

DeadLetterValue is a message its queue gave up on: when, why, and how many times it was delivered.

type DeliveryValue added in v0.33.0

type DeliveryValue struct {
	// Message is what is delivered.
	Message MessageValue
	// Deliveries counts the deliveries, this one included.
	Deliveries int
}

DeliveryValue is one delivery of a message: the message, and how many times it has been delivered, this one included.

type DocumentSink added in v0.32.0

type DocumentSink interface {
	// PutDocument writes the document key with its versions and its trash
	// as they are given.
	PutDocument(ctx context.Context, key string, versions []VersionValue, trashedAt time.Time) error
	// InsertRaw writes a document of a store that keeps no versions, as it
	// rests.
	InsertRaw(ctx context.Context, raw json.RawMessage) error
}

DocumentSink is a store's documents on the database a data copy writes. A sibling of Documents.

type DocumentSource added in v0.32.0

type DocumentSource interface {
	// Documents is the document store the engine runs on, and whether there
	// is one.
	Documents() (Documents, bool)
}

DocumentSource is an engine that says the document store it runs on: itself, or the one what it wraps runs on. A data copy reads and writes a store through it (ADR 0178 C7). A sibling of StoreEngine.

type DocumentValue added in v0.31.0

type DocumentValue struct {
	// JSON is the record as it rests.
	JSON json.RawMessage
	// Value is the entity decoded from JSON, nil until something decoded it;
	// the store's typed facade asserts it to its type.
	Value any
}

DocumentValue is a record as a store's engine holds it (ADR 0179 §2): its JSON as it rests, byte for byte what kit encodes, and the entity once decoded, kept beside it so that a read, an index or a privacy walk does not decode it twice.

type Documents added in v0.32.0

type Documents interface {
	// KeyList yields every key the store holds, in key order.
	KeyList(ctx context.Context) iter.Seq2[string, error]
	// TombstoneList is the trash, in key order: none when the store keeps
	// no versions.
	TombstoneList(ctx context.Context) ([]TombstoneValue, error)
	// VersionList is the versions of the document key, newest first.
	VersionList(ctx context.Context, key string) ([]VersionValue, error)
	// Current is the document key as the store keeps it.
	Current(ctx context.Context, key string) (json.RawMessage, error)
	// KeepsVersions reports whether the store keeps versions.
	KeepsVersions() bool
}

Documents is a store's documents as they rest, as a data copy reads them.

type EntrySource added in v0.32.0

type EntrySource interface {
	// KeyedEntries returns up to limit records as they rest, in key order.
	KeyedEntries(ctx context.Context, limit int) ([]EntryValue, error)
}

EntrySource is an engine that lists its records as they rest with their keys: what a sealing store reads its records by. A sibling of StoreEngine.

type EntryValue added in v0.32.0

type EntryValue struct {
	// Key is the record's key.
	Key string
	// JSON is the record as it rests.
	JSON json.RawMessage
}

EntryValue is a record as it rests, with its key: what an engine lists for a reader that cannot key a record itself.

type EventStream

type EventStream interface {
	// Send writes one event's data.
	Send(data string) error
	// Done is closed when the client left.
	Done() <-chan struct{}
	// Close ends the stream.
	Close() error
}

EventStream is one Server-Sent Events stream: the Studio's live events.

type Executor added in v0.32.0

type Executor interface {
	// ExecContext runs a statement that returns no rows.
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
	// QueryContext runs a query that returns rows.
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
	// QueryRowContext runs a query that returns at most one row.
	QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
}

Executor is what a migration's step runs its statements on: the transaction its migration runs in.

type Folder added in v0.31.0

type Folder interface {
	// Fold rewrites the store's data with only what it holds now.
	Fold(ctx context.Context) error
}

Folder is an engine that keeps what its writes left beside its data, and can fold it in now. A sibling of StoreEngine.

type HTTPConfig

type HTTPConfig struct {
	// Addr is where to listen, "host:port".
	Addr string
	// Shards is how many sockets the engine opens on Addr.
	Shards int
	// ReadHeader, Read, Write and Idle bound a request's phases.
	ReadHeader, Read, Write, Idle time.Duration
	// MaxHeaderBytes bounds a request's header.
	MaxHeaderBytes int
	// Handler answers every request.
	Handler http.Handler
}

HTTPConfig is what kit asks of the HTTP engine: where to listen, its one socket, its bounds, and the handler.

type HTTPServer

type HTTPServer interface {
	// Start binds the address and serves, returning once bound.
	Start(ctx context.Context) error
	// State says what the engine binds and serves.
	State() HTTPState
	// Shutdown drains the engine within ctx.
	Shutdown(ctx context.Context) error
}

HTTPServer is the HTTP engine kit starts, reads and stops.

type HTTPState

type HTTPState struct {
	// Addr is the address the engine bound, "" before it did.
	Addr string
	// Listeners is how many sockets it listens on.
	Listeners int
	// Active are the connections being served, Total those accepted since
	// the start, Rejected those refused.
	Active          int64
	Total, Rejected uint64
}

HTTPState is what the HTTP engine says of itself once it runs: the address it bound, and its connections.

type HandleProvider added in v0.32.0

type HandleProvider interface {
	// Handle sets what dst points at to the SDK's handle of its type.
	Handle(dst any) bool
}

HandleProvider is a value of a subsystem that hands one of the SDK's own handles on: the value dst points at set, and true; false for a handle it has none of. It serves the mailer's spool, still in kit's core, which takes the SDK's types — a Database's transaction manager as the spool's Deferrer, a queue's broker (Broker) as its outbox — until the mailers leave the core (ADR 0179, step 6), and the core never names the type it asks for. A sibling of Database and of Broker.

type IndexSpec added in v0.31.0

type IndexSpec struct {
	// Name reads the index, and names it in a refusal.
	Name string
	// Unique refuses a write that would file two documents under one key.
	Unique bool
	// Keys are a document's keys in the index; an empty key is not indexed.
	Keys func(d DocumentValue) []string
}

IndexSpec declares one secondary index of a store, over documents: the product's index function on its type, wrapped once at the declaration.

type Keyser added in v0.31.0

type Keyser interface {
	// Keys yields the keys above after, in order, then its failure if any.
	Keys(ctx context.Context, after string) iter.Seq2[string, error]
}

Keyser is an engine that lists the keys of its documents, in key order, above after, without reading a document. A sibling of StoreEngine.

type LiveMessageValue added in v0.33.0

type LiveMessageValue struct {
	// VisibleAt is when the message is next delivered.
	VisibleAt time.Time
	// Message is the message.
	Message MessageValue
	// Deliveries counts its deliveries so far.
	Deliveries int
	// Leased reports whether a consumer holds it.
	Leased bool
}

LiveMessageValue is a message waiting in its queue, as it lies: when it is next visible, how many times it was delivered, and whether a consumer holds it.

type MessageMover added in v0.33.0

type MessageMover interface {
	// Messages are up to maxMessages live messages after the identifier
	// after, "" for the first, in their queue's order.
	Messages(ctx context.Context, after string, maxMessages int) ([]LiveMessageValue, error)
	// PutMessage writes live under an identifier of the queue's own, and
	// returns it.
	PutMessage(ctx context.Context, live LiveMessageValue) (string, error)
	// PutDeadLetter writes dead, with its cause, under an identifier of the
	// queue's own, and returns it.
	PutDeadLetter(ctx context.Context, dead DeadLetterValue) (string, error)
}

MessageMover is a Broker whose messages a data copy reads and writes as they lie, without a lease, with their counts and their instants. A sibling of Broker.

type MessageValue added in v0.33.0

type MessageValue struct {
	// EnqueuedAt is when the message was published.
	EnqueuedAt time.Time
	// ID identifies the message in its queue.
	ID string
	// Payload is the message as kit encoded it.
	Payload []byte
}

MessageValue is one message of a queue: its identifier, its payload as kit encoded it, and when it was published.

type MigrationValue added in v0.32.0

type MigrationValue struct {
	// Version orders the migration in its set: non-zero and unique.
	Version uint64
	// Name labels it in the version table.
	Name string
	// Up applies the change.
	Up Step
	// Down reverses it.
	Down Step
}

MigrationValue is one versioned change of a database's schema and its reversal, as kit's migrations are written: the SDK's own, on the standard library's types.

type Migrator added in v0.32.0

type Migrator interface {
	// Plan is the set's pending migrations, oldest first, applying nothing.
	Plan(ctx context.Context) ([]MigrationValue, error)
	// Up applies every pending migration, in order.
	Up(ctx context.Context) error
	// Down reverses the applied migrations above version, newest first.
	Down(ctx context.Context, version uint64) error
}

Migrator is one set of migrations on a database.

type MigratorProvider added in v0.32.0

type MigratorProvider interface {
	// Migrator is the set ms, under the version table table.
	Migrator(table string, ms []MigrationValue) (Migrator, error)
}

MigratorProvider is a Database that runs a set of migrations under a version table of its own, and so a lock of its own. A sibling of Database.

type ProfilerConfig

type ProfilerConfig struct {
	// Heap folds the live heap onto g's nodes; source says where a function
	// of a module lies, nil when it knows none.
	Heap func(g *model.Graph, source SourceFunc) (*model.Profile, error)
	// Goroutines groups every goroutine of the process, read at at.
	Goroutines func(at time.Time) (*model.Goroutines, error)
}

ProfilerConfig is the Studio's profiler: the live heap folded onto the graph's nodes, and every goroutine grouped.

type QueueConfig added in v0.33.0

type QueueConfig struct {
	// Name names the queue's node in a refusal: the consumer's or the
	// mailer's node ID.
	Name string
	// Dir is the directory a file queue lies in; with no Database and no
	// Dir, the queue is in memory.
	Dir string
	// Database keeps the queue, nil when Dir or memory does: a scope the
	// store subsystem's Database opened, whose transaction a publication in
	// it joins.
	Database Database
	// Table is the queue's table on Database.
	Table string
	// Policy is how the queue leases, retries and bounds its messages.
	Policy QueuePolicyValue
	// Clock is the app's clock, which the queue stamps and waits on.
	Clock Clock
	// Seal, when set, seals every payload on its way in — a mail's, in a
	// mailer's outbox on a database —, and Unseal opens one on its way out;
	// MaxPayload bounds a payload before it is sealed.
	Seal func(ctx context.Context, payload []byte) ([]byte, error)
	// Unseal is the payload a box holds, the box as it lies when it does
	// not open.
	Unseal func(ctx context.Context, box []byte) []byte
	// MaxPayload bounds a payload Seal seals.
	MaxPayload int
	// Wrap, when a test sets it, stands in front of the queue the subsystem
	// opens: a func(queue.Broker) queue.Broker of the SDK's queue, which
	// kit's core does not name. Nil in every app a product builds.
	Wrap any
}

QueueConfig is what kit asks of one queue: where it lies, its policy, the app's clock, and for a mailer's outbox the sealing of what it keeps.

type QueueDriverConfig added in v0.33.0

type QueueDriverConfig struct {
	// Open opens one queue, as cfg places it: on a database, in a
	// directory, or in memory.
	Open func(cfg QueueConfig) (Broker, error)
	// TableMigration is the migration that makes the queue table on a
	// database of the dialect named, at version.
	TableMigration func(dialect, table string, version uint64) (MigrationValue, error)
	// DoNotRetry is err as a delivery's handler returns it when no retry
	// can help: its queue dead-letters the message at once.
	DoNotRetry func(err error) error
	// NotRetryable reports whether err, a delivery's handler's, says that no
	// retry can help: what DoNotRetry returned, the product's own included.
	NotRetryable func(err error) bool
}

QueueDriverConfig is what framework/kit/queue plugs into kit: how a consumer's queue opens, the migration that makes its table on a database, and how a delivery's handler says that no retry can help.

type QueuePolicyValue added in v0.33.0

type QueuePolicyValue struct {
	// VisibilityTimeout is how long a delivery is leased.
	VisibilityTimeout time.Duration
	// RetryDelay is the wait after a message's first failure, doubled after
	// each, up to MaxRetryDelay.
	RetryDelay time.Duration
	// MaxRetryDelay bounds the wait before a retry; zero leaves it unbound.
	MaxRetryDelay time.Duration
	// MaxDeliveries is how often a message is delivered before it is
	// dead-lettered.
	MaxDeliveries int
	// MaxMessageBytes bounds a message; zero is the queue's own bound.
	MaxMessageBytes int
}

QueuePolicyValue is how a queue leases, retries and bounds its messages: the SDK's queue policy, in kit's terms.

type Refusal added in v0.32.0

type Refusal uint8

Refusal is a kind of refusal of a store's engine or a database, as kit words it.

const (
	// RefusalNone is no refusal kit words.
	RefusalNone Refusal = iota
	// RefusalNotFound is no document under the key, or under the index's
	// key.
	RefusalNotFound
	// RefusalExists is a document already under the key an insertion names.
	RefusalExists
	// RefusalUniqueTaken is another document under a unique index's key.
	RefusalUniqueTaken
	// RefusalKeyEmpty is a document whose key is empty.
	RefusalKeyEmpty
	// RefusalKeyChanged is an update that changes the document's key.
	RefusalKeyChanged
	// RefusalIndexUnknown is an index the store does not declare.
	RefusalIndexUnknown
	// RefusalIndexNotUnique is a lookup on an index that is not unique.
	RefusalIndexNotUnique
	// RefusalIndexBroken is stored documents that break a unique index.
	RefusalIndexBroken
	// RefusalUndecodable is a record that does not decode into its type.
	RefusalUndecodable
	// RefusalUnencodable is an entity that does not encode.
	RefusalUnencodable
	// RefusalPersist is a write the store could not keep.
	RefusalPersist
	// RefusalLoad is a store that could not be loaded; its "problem" field
	// says why.
	RefusalLoad
	// RefusalClosed is a call on a closed engine.
	RefusalClosed
	// RefusalUnconfirmed is a write that stands but whose survival across a
	// power loss is in doubt.
	RefusalUnconfirmed
	// RefusalVersionsNotKept is a call on the versions of a store that keeps
	// none.
	RefusalVersionsNotKept
	// RefusalVersionsRewrite is a rewrite of versions that adds or
	// renumbers one.
	RefusalVersionsRewrite
	// RefusalNotTrashed is no record in the trash under the key.
	RefusalNotTrashed
	// RefusalKeyTooLong is a key longer than a database's key columns hold;
	// its "max" field says how long they hold.
	RefusalKeyTooLong
	// RefusalStatement is a statement the database did not complete.
	RefusalStatement
	// RefusalTxClosed is a call with the context of a transaction that
	// ended.
	RefusalTxClosed
	// RefusalTxFailed is a transaction or a savepoint the database would
	// not open, commit or roll back.
	RefusalTxFailed
	// RefusalOutOfOrder is a migration older than one already applied; its
	// "applied" field names the newer.
	RefusalOutOfOrder
)

The kinds of refusal.

type RefusalError added in v0.32.0

type RefusalError struct {
	// Err is what the engine met.
	Err error
	// Kind is how kit words it.
	Kind Refusal
}

RefusalError is an engine's refusal of one kind: the error it met, and the kind kit words it by.

func (*RefusalError) Error added in v0.32.0

func (e *RefusalError) Error() string

Error is what the engine met's.

func (*RefusalError) Unwrap added in v0.32.0

func (e *RefusalError) Unwrap() error

Unwrap is what the engine met.

type Reindexer added in v0.32.0

type Reindexer interface {
	// Reindex files every record's index rows again.
	Reindex(ctx context.Context) error
}

Reindexer is an engine on a database that files its index rows again. A sibling of StoreEngine.

type SourceFunc

type SourceFunc func(file string, line int, fn string) *model.Source

SourceFunc says where the function fn, at file:line, lies in the product, nil when it knows none.

type StampValue added in v0.32.0

type StampValue struct {
	// Meta is kept with the version the write makes.
	Meta map[string]string
	// InPlace makes the write change the document without making a version.
	InPlace bool
}

StampValue is what a write says about the version it makes: who made it and which command, kept with the version; and whether it changes the document in place, without a version of its own.

type Step added in v0.32.0

type Step func(ctx context.Context, ex Executor) error

Step is one direction of a migration, run on ex.

type StoreConfig added in v0.31.0

type StoreConfig struct {
	// Name is the store's, as a log line and a rollback name it.
	Name string
	// Key is a document's key: the product's key function on its type,
	// wrapped once at the declaration. It reads the document's Value, which
	// the engine decodes first unless KeyAtRest gives the key.
	Key func(d DocumentValue) string
	// KeyAtRest, when set, gives the key of a record as it rests, without
	// decoding it; false when it cannot.
	KeyAtRest func(raw json.RawMessage) (string, bool)
	// Decode is the entity a document's JSON holds, which the engine keeps
	// as the document's Value.
	Decode func(raw json.RawMessage) (any, error)
	// Indexes are the store's secondary indexes.
	Indexes []IndexSpec
	// Data is the data directory the store rests in — the SDK's writable
	// file system, which the engine asserts — and Path its snapshot there;
	// a nil Data and a nil Database keep the store in memory.
	Data fs.FS
	// Path is the store's snapshot in Data.
	Path string
	// Database keeps the store, nil when the data directory or memory does:
	// a scope the store subsystem's Database opened.
	Database Database
	// Table is the store's table on Database.
	Table string
	// IndexKey is the key a table's index keys are hashed under, nil for
	// none: an index key reaches the table as its keyed hash.
	IndexKey func(index, key string) []byte
	// Call is the context one call of the engine on Database runs with: on
	// the transaction ctx carries for it, else on the pool, within the
	// database's timeout; done ends it.
	Call func(ctx context.Context, write bool) (call context.Context, done func(), err error)
	// Versions is how many former versions of each record the engine keeps,
	// none when zero; Clock stamps them.
	Versions int
	// Clock is the app's clock, which stamps a version.
	Clock func() time.Time
	// Held reports whether a record's versions are held, and no write may
	// prune them: asked with the write's context, on a database inside its
	// transaction.
	Held func(ctx context.Context, key string) bool
	// Stamp is what a write under ctx says about the version it makes.
	Stamp func(ctx context.Context) StampValue
	// Transaction is kit's transaction, which the engine's writes take part
	// in.
	Transaction Transaction
}

StoreConfig is what kit asks of one store's engine: the store, its key and its indexes over documents, where it rests and what it keeps, and how its writes take part in kit's transactions.

type StoreDriverConfig added in v0.31.0

type StoreDriverConfig struct {
	// Open opens the engine of one store, as cfg places it: loaded from the
	// data directory, empty in memory, or on a database.
	Open func(cfg StoreConfig) (StoreEngine, error)
	// Database opens kit's scope on one database's pool.
	Database func(cfg DatabaseConfig) (Database, error)
	// TableMigration is the migration that makes the table t on a database
	// of the dialect named, at version.
	TableMigration func(dialect string, t TableSpec, version uint64) (MigrationValue, error)
}

StoreDriverConfig is what framework/kit/store plugs into kit: how a store's engine opens, how kit opens its scope on a database, and the migration that makes one of kit's tables.

type StoreEngine added in v0.31.0

type StoreEngine interface {
	// Get returns the document under key.
	Get(ctx context.Context, key string) (DocumentValue, error)
	// List returns every document, in key order.
	List(ctx context.Context) ([]DocumentValue, error)
	// Filter returns the documents keep accepts, in key order.
	Filter(ctx context.Context, keep func(d DocumentValue) bool) ([]DocumentValue, error)
	// Lookup returns the document a unique index files under key.
	Lookup(ctx context.Context, index, key string) (DocumentValue, error)
	// Find returns the documents an index files under key, in key order.
	Find(ctx context.Context, index, key string) ([]DocumentValue, error)
	// Count says how many documents the store holds.
	Count(ctx context.Context) (int, error)
	// Entries returns up to limit documents as they rest, in key order.
	Entries(ctx context.Context, limit int) ([]json.RawMessage, error)
	// Write stores d as mode says. The document and its index keys are kept
	// together, or neither.
	Write(ctx context.Context, d DocumentValue, mode WriteMode) error
	// Update applies fn to the document under key and stores the result,
	// atomically with respect to every other write of the store.
	Update(ctx context.Context, key string, fn func(d *DocumentValue) error) (DocumentValue, error)
	// Delete removes the document under key.
	Delete(ctx context.Context, key string) error
	// Watch registers the functions told the key of every document written
	// and deleted, once the write stands.
	Watch(onWrite, onDelete func(key string))
	// Close releases the engine.
	Close() error
}

StoreEngine is what a store runs on, over documents (ADR 0179 §2): the non-generic engine under Store[T]. Its refusals are kit's (Refusal): the engine translates the SDK's before they reach the core. Every call takes the caller's context, which carries the transaction the call joins. It grows by the sibling interfaces below, never by a method (the SDK's ADR 0039).

type TableSpec added in v0.32.0

type TableSpec struct {
	// Name is the table's.
	Name string
	// VersionsOf is, for a store's versions, the store's table, from which
	// the versions' table is named.
	VersionsOf string
}

TableSpec is one of kit's tables on a database, as the store subsystem's migration makes it: a store's, or a store's versions beside the store's table VersionsOf. A consumer's queue's table is the queue subsystem's (QueueDriverConfig's TableMigration).

type Ticker added in v0.33.0

type Ticker interface {
	// C receives the clock's instant at each tick.
	C() <-chan time.Time
	// Stop stops the ticker.
	Stop()
	// Reset makes the ticker fire every d.
	Reset(d time.Duration)
}

Ticker is a ticker of a Clock.

type Timer added in v0.33.0

type Timer interface {
	// C receives the clock's instant when the timer fires.
	C() <-chan time.Time
	// Stop stops the timer, and reports whether it had not fired.
	Stop() bool
	// Reset makes the timer fire once d passed, and reports whether it had
	// not fired.
	Reset(d time.Duration) bool
}

Timer is a timer of a Clock.

type TombstoneValue added in v0.31.0

type TombstoneValue struct {
	// Key is the trashed record's key.
	Key string
	// At is when the record was trashed, in UTC.
	At time.Time
}

TombstoneValue is one record in a store's trash: its key, and when it was trashed.

type Transaction added in v0.32.0

type Transaction interface {
	// Local reports whether ctx runs in a transaction that holds the data's
	// writer turn: a write in the data directory or in memory then records
	// what it replaces.
	Local(ctx context.Context) bool
	// Undo keeps restore, which a rollback of the transaction ctx carries
	// runs; nothing outside one. store names the store in a log line.
	Undo(ctx context.Context, store string, restore func(ctx context.Context) error)
	// AtCommit holds fn until the transaction ctx carries commits, and
	// reports whether it did: false outside one, where the caller runs it
	// now.
	AtCommit(ctx context.Context, fn func()) bool
	// Retell keeps fn, which announces a write on a database again when the
	// transaction ctx carries rolls it back.
	Retell(ctx context.Context, fn func())
}

Transaction is kit's transaction as a store's engine takes part in it (ADR 0139, ADR 0178): the core implements it, an engine calls it with its caller's context.

type Trasher added in v0.31.0

type Trasher interface {
	// Trash moves the record under key to the trash: gone from every read,
	// its index keys freed, its versions kept.
	Trash(ctx context.Context, key string) error
	// Untrash brings the record trashed under key back as it was.
	Untrash(ctx context.Context, key string) error
	// Purge empties the trash of the record trashed under key, its versions
	// with it.
	Purge(ctx context.Context, key string) error
	// Tombstones are every record in the trash, in key order.
	Tombstones(ctx context.Context) ([]TombstoneValue, error)
}

Trasher is an engine that keeps a trash. A sibling of StoreEngine.

type VersionKeeper added in v0.31.0

type VersionKeeper interface {
	// StoredVersions are the versions of the record under key, newest
	// first, the current one first.
	StoredVersions(ctx context.Context, key string) ([]VersionValue, error)
	// RewriteVersions rewrites the former versions of the record under key
	// as fn returns them: fn may drop a version or change what one holds,
	// never add or renumber one.
	RewriteVersions(ctx context.Context, key string, fn func(vs []VersionValue) ([]VersionValue, error)) error
}

VersionKeeper is an engine that keeps its records' versions. A sibling of StoreEngine.

type VersionValue added in v0.31.0

type VersionValue struct {
	// Number counts a record's versions from 1.
	Number uint64
	// At is when the write that made the version ran, in UTC.
	At time.Time
	// Meta is what the write said about it: who made it, which command.
	Meta map[string]string
	// JSON is the record as the version holds it.
	JSON json.RawMessage
}

VersionValue is one version of a record: its number, when the write that made it ran, what that write said about it, and the record as it held it.

type VersionWeightValue added in v0.31.0

type VersionWeightValue struct {
	// Former is how many former versions the store keeps.
	Former int
	// Trashed is how many records are in the trash.
	Trashed int
	// Bytes is what the former versions and the trashed records weigh.
	Bytes int64
}

VersionWeightValue is what a store keeps beyond the records it holds: its former versions and its trash, counted and weighed.

type VersionWeighter added in v0.31.0

type VersionWeighter interface {
	// VersionWeight is what the store's versions and trash weigh.
	VersionWeight(ctx context.Context) (VersionWeightValue, error)
}

VersionWeighter is an engine that says what its records' versions weigh. A sibling of StoreEngine.

type WriteMode added in v0.31.0

type WriteMode int

WriteMode says what a write expects to find under the document's key.

const (
	// WriteUpsert writes whatever the key holds: a creation or a
	// replacement.
	WriteUpsert WriteMode = iota
	// WriteInsert expects nothing under the key, and is refused otherwise.
	WriteInsert
	// WriteReplace expects a document under the key, and is refused
	// otherwise: never a resurrection.
	WriteReplace
)

The write modes.

Jump to

Keyboard shortcuts

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