command

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: BSD-3-Clause Imports: 43 Imported by: 0

Documentation

Overview

Package command implements aki's command table and dispatch pipeline. It turns a parsed argument vector into a reply by looking the command up in the table, checking arity and auth, and calling the command's handler. It is the Handler the networking layer drives (doc 07).

This milestone (M1) builds the dispatch core and the connection-group commands. The data-type commands (strings, lists, ...) register into the same table in later slices; the keyspace they touch is reached through the handler context, which gains those accessors when the keyspace lands.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CountSnapshot

func CountSnapshot(snap rdb.Snapshot, onlyDB int) int

CountSnapshot returns the number of keys in a snapshot, optionally limited to a single source database. The import dry run uses it.

func LoadSnapshot

func LoadSnapshot(ks *keyspace.Keyspace, snap rdb.Snapshot, onlyDB int, replace bool) (int, error)

LoadSnapshot writes the entries from snap into ks. When onlyDB is zero or greater only that source database is imported. When replace is false a key that already exists is left untouched; when true it is overwritten. It returns the number of keys written. The caller commits the keyspace.

func SnapshotKeyspace

func SnapshotKeyspace(ks *keyspace.Keyspace) (rdb.Snapshot, error)

SnapshotKeyspace copies every live key in every database of ks into an rdb.Snapshot. The caller is expected to hold whatever lock the keyspace needs; the offline tools own the keyspace exclusively and the server takes the engine lock through snapshotAll.

Types

type CmdDesc

type CmdDesc struct {
	Name    string // lowercase, e.g. "get", "hello"
	SubName string // "container|sub" for subcommands, e.g. "command|count"
	Group   CmdGroup
	Since   string // Redis version the command first appeared in

	// Arity follows the Redis convention and includes the command name itself:
	// a positive value is an exact count, a negative value is a minimum of its
	// absolute value.
	Arity int

	Flags FlagSet

	// Fixed key positions (1-based). FirstKey 0 means the command takes no keys.
	FirstKey int
	LastKey  int
	Step     int

	// Handler runs the command and writes its reply through ctx.Conn.
	Handler func(ctx *Ctx)

	// SubCmds holds the subcommands of a container command (COMMAND, CONFIG, ...).
	SubCmds []*CmdDesc
}

CmdDesc describes one command in the table: its identity, arity, flags, key positions, and handler. It is the single source of truth for dispatch, arity checking, and introspection (doc 07 §1).

type CmdGroup

type CmdGroup uint8

CmdGroup is the functional group a command belongs to, used by COMMAND and by ACL categorisation (doc 07 §1.1).

const (
	GroupString CmdGroup = iota
	GroupBitmap
	GroupHyperLogLog
	GroupGeo
	GroupList
	GroupSet
	GroupSortedSet
	GroupHash
	GroupStream
	GroupPubSub
	GroupTransactions
	GroupScripting
	GroupGeneric
	GroupServer
	GroupConnection
	GroupCluster
)

type Config

type Config struct {
	// Databases is the number of logical databases. SELECT accepts 0..Databases-1.
	Databases int
	// RequirePass is the default user password. Empty means no auth is required.
	RequirePass string
	// AclFile is the path to an external ACL file. Empty disables ACL LOAD/SAVE
	// and keeps users in memory only.
	AclFile string
	// Version is reported by HELLO.
	Version string
	// Mode is reported by HELLO: "standalone", "sentinel", or "cluster".
	Mode string
	// Engine is the keyspace the data commands operate on. It may be nil for a
	// connection-only server (the connection-group commands need no keyspace).
	Engine *Engine
}

Config holds the server settings the dispatcher needs.

type Ctx

type Ctx struct {
	Conn *networking.Conn
	Argv [][]byte
	// contains filtered or unexported fields
}

Ctx carries everything a handler needs: the connection it replies on, the argument vector, and back-references to the dispatcher and session. Later milestones add keyspace accessors here.

func (*Ctx) MarkPropagate

func (ctx *Ctx) MarkPropagate()

MarkPropagate makes the running command propagate to the AOF and replicas regardless of the keyspace dirty counter. A handler calls it after a change that must replicate but does not live in the keyspace, such as FUNCTION LOAD.

type Dispatcher

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

Dispatcher routes parsed commands to their handlers. It satisfies networking.Handler.

func New

func New(cfg Config) *Dispatcher

New builds a Dispatcher with the connection-group and data-type commands.

func (*Dispatcher) AdminAddr

func (d *Dispatcher) AdminAddr() string

AdminAddr returns the address the endpoint is listening on, or "" when it is not running. The server command prints it; tests read it to build request URLs.

func (*Dispatcher) ApplyGCTuning

func (d *Dispatcher) ApplyGCTuning()

ApplyGCTuning applies go-gogc and go-memlimit to the runtime. The server command calls it once at startup, and CONFIG SET calls it again whenever either value changes, so a change takes effect at once.

func (*Dispatcher) ApplyNetworkConfig

func (d *Dispatcher) ApplyNetworkConfig()

ApplyNetworkConfig pushes timeout, tcp-keepalive, and proto-max-bulk-len to the server. The server command calls it once at startup after the server is attached, and CONFIG SET calls the per-knob setters when a value changes.

func (*Dispatcher) Handle

func (d *Dispatcher) Handle(c *networking.Conn, argv [][]byte)

Handle implements networking.Handler. It runs the dispatch pipeline: look up the command, check arity, check auth, then call the handler.

func (*Dispatcher) LoadACLFromKeyspace

func (d *Dispatcher) LoadACLFromKeyspace() error

LoadACLFromKeyspace restores ACL users persisted in the .aki system table. It runs once at startup when no external aclfile is configured. An empty table leaves the default user built by New in place.

func (*Dispatcher) LoadFunctions

func (d *Dispatcher) LoadFunctions(sources []string)

LoadFunctions rebuilds the function registry from a set of library sources. The startup --load-rdb import uses it to bring over the functions an imported dump.rdb carried in its FUNCTION2 records.

func (*Dispatcher) LoadFunctionsFromKeyspace

func (d *Dispatcher) LoadFunctionsFromKeyspace() error

LoadFunctionsFromKeyspace rebuilds the function registry from the libraries persisted in the .aki system table. It runs once at startup before any RDB import, so an explicit --load-rdb still applies on top. An empty table leaves the registry empty, the normal first-boot state.

func (*Dispatcher) LoadScriptsFromKeyspace

func (d *Dispatcher) LoadScriptsFromKeyspace() error

LoadScriptsFromKeyspace loads the persisted scripts back into the cache at startup. Each body is re-added through put, which recomputes the same digest, so the key in the table and the cache key always agree. An empty table leaves the cache empty.

func (*Dispatcher) LogClose

func (d *Dispatcher) LogClose()

LogClose releases the log file and syslog handles. The server command defers it.

func (*Dispatcher) LogNotice

func (d *Dispatcher) LogNotice(msg string, kv ...any)

LogNotice writes a notice-level line. The server command uses it for startup and shutdown messages. The variadic arguments are alternating key and value pairs.

func (*Dispatcher) LogStart

func (d *Dispatcher) LogStart() error

LogStart opens the logfile and connects to syslog. The server command calls it at startup.

func (*Dispatcher) MetricsAddr

func (d *Dispatcher) MetricsAddr() string

MetricsAddr returns the address the endpoint is listening on, or "" when it is not running. The server command prints it; tests read it to build a scrape URL.

func (*Dispatcher) OnDisconnect

func (d *Dispatcher) OnDisconnect(c *networking.Conn)

OnDisconnect drops a connection's pub/sub subscriptions when its read loop exits, so a published message is never delivered to a gone client. It satisfies networking.DisconnectHandler.

func (*Dispatcher) OnPanic

func (d *Dispatcher) OnPanic(cause any, stack []byte)

OnPanic is the panic hook the network server calls from its per-connection recover. It writes the crash report and exits the process, because a panic leaves engine state mid-mutation and aki cannot safely keep serving. The network layer holds a PanicHandler reference to this method.

func (*Dispatcher) PersistFunctions

func (d *Dispatcher) PersistFunctions()

PersistFunctions mirrors the loaded function libraries into the .aki system table. The server uses it at startup to make an imported dump.rdb's functions durable in the data file.

func (*Dispatcher) ReopenLog

func (d *Dispatcher) ReopenLog() error

ReopenLog closes and reopens the logfile. The server command calls it on SIGHUP so logrotate can rotate the file.

func (*Dispatcher) SetConfig

func (d *Dispatcher) SetConfig(name, value string) error

SetConfig validates and applies one directive the same way CONFIG SET does, then runs its side effects. The server command uses it to apply command-line flags like logfile and loglevel before logging starts.

func (*Dispatcher) SetReady

func (d *Dispatcher) SetReady(v bool)

SetReady marks the server as accepting clients. The server command calls it once the listener is up. The HTTP /ready endpoint reads it.

func (*Dispatcher) SetServer

func (d *Dispatcher) SetServer(s *networking.Server)

SetServer gives the dispatcher a handle to the network server so CLIENT and INFO can enumerate live connections. The wiring happens after both are built, since the server takes the dispatcher as its handler.

func (*Dispatcher) SetShutdown

func (d *Dispatcher) SetShutdown(fn func())

SetShutdown installs the callback the handler fires to begin a graceful shutdown. The server command wires it to its main-loop signal.

func (*Dispatcher) StartAdmin

func (d *Dispatcher) StartAdmin() error

StartAdmin starts the admin endpoint when admin-port is set. A port of 0 leaves it disabled and returns nil. The server command calls it once at startup, alongside StartMetrics. The server runs in its own goroutine.

func (*Dispatcher) StartBackground

func (d *Dispatcher) StartBackground()

StartBackground launches the server cron, a goroutine that runs the active expiry cycle hz times a second. The network server calls it once at startup. Tests that drive expiry directly do not start it; they call runActiveExpire instead so the timing is deterministic.

func (*Dispatcher) StartMetrics

func (d *Dispatcher) StartMetrics() error

StartMetrics starts the Prometheus endpoint when metrics-port is set. A port of 0 leaves it disabled and returns nil. The server runs in its own goroutine.

func (*Dispatcher) StartProfiler

func (d *Dispatcher) StartProfiler() error

StartProfiler launches continuous profiling when continuous-profiling is on. It is a no-op returning nil when the feature is off. The server command calls it once at startup, alongside StartMetrics.

func (*Dispatcher) StopAdmin

func (d *Dispatcher) StopAdmin()

StopAdmin shuts the endpoint down. It is safe to call when the endpoint was never started.

func (*Dispatcher) StopBackground

func (d *Dispatcher) StopBackground()

StopBackground stops the cron goroutine and waits for it to exit. It is safe to call when the cron was never started.

func (*Dispatcher) StopMetrics

func (d *Dispatcher) StopMetrics()

StopMetrics shuts the endpoint down. It is safe to call when the endpoint was never started.

func (*Dispatcher) StopProfiler

func (d *Dispatcher) StopProfiler()

StopProfiler stops the profiler goroutine and waits for it to exit. It is safe to call when the profiler was never started.

func (*Dispatcher) StopReplication

func (d *Dispatcher) StopReplication()

StopReplication signals the replica client goroutine to exit and waits for it to return. It must run before the keyspace and pager close on shutdown, so the apply loop never touches a closed pager. Safe to call on a master: it returns at once when no replica link is active.

func (*Dispatcher) WriteCrashReport

func (d *Dispatcher) WriteCrashReport(cause any, stack []byte)

WriteCrashReport formats a bug report for a panic and writes it to the log sink. It does nothing when crash-log-enabled is off. The memory section is included only when crash-memlog-enabled is on. The report goes to the log file, or to stderr when no log file is configured, and is also mirrored to stderr when the log file is elsewhere so an operator watching the console still sees the crash.

type Engine

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

Engine is the command layer's handle on the keyspace. It serializes every access with a single mutex, which is the one-writer assumption the keyspace makes at this milestone. The sharded writer model from doc 05 §7 replaces this global lock in a later slice.

func NewEngine

func NewEngine(ks *keyspace.Keyspace) *Engine

NewEngine wraps a keyspace for use by the dispatcher.

type FlagSet

type FlagSet uint64

FlagSet is a bitmask of command flags (doc 07 §1.2, §2). Only the flags the current milestone observes are acted on; the rest are carried for COMMAND introspection and future pipeline stages.

const (
	FlagWrite FlagSet = 1 << iota
	FlagReadOnly
	FlagDenyOOM
	FlagAdmin
	FlagPubSub
	FlagNoScript
	FlagBlocking
	FlagLoading
	FlagStale
	FlagNoAuth
	FlagFast
	FlagMovableKeys
	FlagNoMulti
	FlagNoMandatoryKeys
	FlagAllowBusy
)

func (FlagSet) Has

func (s FlagSet) Has(f FlagSet) bool

Has reports whether every bit in f is set in s.

type Table

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

Table is the command registry: a name -> descriptor map built once at startup from a slice of descriptors. Container commands also index their subcommands.

func NewTable

func NewTable(cmds []*CmdDesc) *Table

NewTable builds a Table from the given descriptors. A descriptor with a non-empty SubName is not a top-level entry; it is reached through its parent's SubCmds list.

func (*Table) Count

func (t *Table) Count() int

Count returns the number of top-level commands in the table, which is what COMMAND COUNT reports.

Jump to

Keyboard shortcuts

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