Documentation
¶
Overview ¶
Package resp Tellstone Redis-Compatible Wire Protocol File: acl.go Description: ACL command family (SETUSER, DELUSER, LIST, LOG) — the Redis-flavored management alias over the RBAC policy store. Users bind to a role plus password options exactly like ROLE SETUSER; LIST renders each user with its role's command and namespace permissions but never a password hash; LOG returns the recent auth-failure buffer. Reply building is RESP2 only; the binary protocol carries its own wire encoding.
Authors:
Maximilian Hagen
Package resp Tellstone Redis-Compatible Wire Protocol File: command.go Description: COMMAND command family (COUNT, DOCS, INFO, LIST, HELP). Introspection surface for the RESP server: redis-cli and cluster-aware clients probe it during the handshake to learn the server's capabilities — which commands exist, their arity, and where the key arguments sit. The table is static because Tellstone's command set is fixed at build time; subcommands nest under their parent (ROLE, ACL, COMMAND) exactly like Valkey. Reply building is RESP2 only; the binary protocol carries its own wire encoding and does not expose this surface.
Authors:
Maximilian Hagen
Package resp Tellstone Redis-Compatible Wire Protocol File: handshake.go Description: Traffic-independent enforcement of the TLS handshake deadline. Connections handed to the TLS state machine — on accept for implicit TLS, on upgrade for STARTTLS — are registered here and swept from the gnet engine ticker, so a client that stops sending after the transition cannot hold a socket, its read buffer, and its TLS state past the deadline.
Authors:
Surafel Workayehu
Package resp Tellstone Redis-Compatible Wire Protocol File: protocol.go Description: Zero-allocation RESP2 (Redis Serialization Protocol) codec. Parses multibulk command frames directly out of the network read buffer and provides append-style reply encoders. Used by the optional RESP listener so Tellstone can be driven by standard tooling (redis-benchmark, memtier_benchmark) for cross-system comparison.
Authors:
Maximilian Hagen
Package resp Tellstone Redis-Compatible Wire Protocol File: respreply.go Description: Reply encoder that adapts the shared command layer's Reply contract to RESP2 output. The encoder appends into the connection's reusable buffer so the GET, SET, and DEL path stays allocation-free; only the error paths build strings.
Authors:
Maximilian Hagen
Package resp Tellstone Redis-Compatible Wire Protocol File: role.go Description: ROLE command family (CREATE, SETUSER, DELUSER, DELETE, LIST, GETUSER). Mutations delegate to the rbac.Store helpers, which clone the active snapshot and republish it with one atomic swap, so readers always observe a complete policy. Reply building is RESP2 only; the binary protocol carries its own wire encoding.
Authors:
Maximilian Hagen
Package resp Tellstone Redis-Compatible Wire Protocol File: server.go Description: Optional gnet event-loop server speaking RESP2, reusing the shared storage engine via a small Store interface. Supports PING, GET, SET (with optional EX/PX), DEL, and AUTH; unknown commands return an error without dropping the connection. Exists so Tellstone can be driven by standard Redis tooling (redis-benchmark, memtier_benchmark) for cross-system comparison. Supports optional implicit TLS 1.3 or an explicit STARTTLS in-place upgrade via the internal TLS library. When a server password is configured (--require-pass / TSD_REQUIRE_PASS), connections must authenticate via AUTH before issuing commands other than PING and QUIT.
Authors:
Maximilian Hagen
Index ¶
- func AppendArray(dst []byte, n int) []byte
- func AppendBulk(dst, b []byte) []byte
- func AppendError(dst []byte, s string) []byte
- func AppendInt(dst []byte, n int64) []byte
- func AppendNullBulk(dst []byte) []byte
- func AppendSimpleString(dst []byte, s string) []byte
- func EqualFold(a []byte, b string) bool
- func Parse(buf []byte, dst [][]byte) (args [][]byte, consumed int, err error)
- type Server
- func (s *Server) BytesRead() uint64
- func (s *Server) BytesWritten() uint64
- func (s *Server) ConnectedClients() uint64
- func (s *Server) ListenAndServe() error
- func (s *Server) OnBoot(eng gnet.Engine) gnet.Action
- func (s *Server) OnClose(c gnet.Conn, err error) (action gnet.Action)
- func (s *Server) OnOpen(c gnet.Conn) (out []byte, action gnet.Action)
- func (s *Server) OnTick() (time.Duration, gnet.Action)
- func (s *Server) OnTraffic(c gnet.Conn) gnet.Action
- func (s *Server) ProtocolErrors() uint64
- func (s *Server) Shutdown(ctx context.Context) error
- func (s *Server) TotalConnections() uint64
- type Store
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AppendArray ¶ added in v1.1.0
AppendArray appends a RESP array header ("*<n>\r\n").
func AppendBulk ¶
AppendBulk appends a RESP bulk string ("$<len>\r\n<b>\r\n").
func AppendError ¶
AppendError appends a RESP error ("-<s>\r\n").
func AppendNullBulk ¶
AppendNullBulk appends a RESP2 null bulk string ("$-1\r\n").
func AppendSimpleString ¶
AppendSimpleString appends a RESP simple string ("+<s>\r\n").
func EqualFold ¶
EqualFold reports whether the ASCII command token a equals the upper-case literal b case-insensitively. b must already be upper-case (e.g. "GET").
func Parse ¶
Parse decodes a single RESP2 multibulk command from buf, appending the argument slices (which point INTO buf) to dst[:0]. It returns the arguments, the number of bytes consumed, and an error. errIncomplete means buf needs more data; errProtocol means malformed framing.
Only the multibulk form (*<n>\r\n $<len>\r\n<bytes>\r\n ...) is supported, which is what redis-benchmark and memtier_benchmark emit.
Types ¶
type Server ¶
type Server struct {
gnet.BuiltinEventEngine
// contains filtered or unexported fields
}
Server is an edge-triggered RESP2 listener backed by gnet.
func NewServer ¶
func NewServer(addr string, store Store, shards []*shard.Shard, logger log.Logger, tlsConfigs *tlslib.ConfigStore, requirePass string, startTLS bool, policy *rbac.Store, provider oauth.Provider, audit *audit.LogEngine) *Server
NewServer creates a RESP server bound to addr that dispatches commands to store. shards is optional — if nil, per-shard metrics are not tracked. tlsConfigs is optional — if nil, plaintext TCP is used. When configured, each accepted connection atomically loads the latest immutable TLS configuration. requirePass is optional — if empty, AUTH is a no-op and connections start authenticated; otherwise it is hashed once at startup and clients must AUTH before issuing commands. startTLS keeps the RESP listener plaintext until a client successfully issues STARTTLS. policy is optional — if nil, RBAC is disabled and every authenticated command is allowed; otherwise AUTH resolves per-user credentials and sessions gate data commands. audit is the shared audit engine; it must be non-nil (pass a disabled engine when audit logging is off) and is always called without a nil guard.
func (*Server) BytesWritten ¶
func (*Server) ConnectedClients ¶
func (*Server) ListenAndServe ¶
ListenAndServe starts the multi-reactor epoll event loop (blocking).
func (*Server) OnTick ¶ added in v1.1.0
OnTick sweeps the pre-handshake registry. gnet runs it on a dedicated goroutine started alongside the event loops, never on one of them, so it must touch only concurrency-safe state — see handshakeSweeper. The interval is a tenth of the deadline: a stalled socket is then reaped within 10% of it, and a single knob (handshakeTimeout) shrinks both for tests.
func (*Server) OnTraffic ¶
OnTraffic parses every complete command currently buffered, batches all replies into a single write, and advances the inbound buffer once — which makes pipelined workloads (redis-benchmark -P / memtier --pipeline) amortize syscalls.
func (*Server) ProtocolErrors ¶
func (*Server) Shutdown ¶
Shutdown gracefully stops the event loop, waiting for in-flight connections to drain or ctx to expire. It blocks until ListenAndServe has reached OnBoot, so it is safe to call concurrently with ListenAndServe from another goroutine (e.g. a signal handler).
func (*Server) TotalConnections ¶
type Store ¶
type Store interface {
Get(key string) ([]byte, bool)
Set(key string, value []byte, ttl time.Duration) error
Delete(key string) bool
}
Store is the subset of the storage engine the RESP server needs. *storage.Engine satisfies it directly, which keeps this package decoupled and easy to test with a fake.