Help us shape the future of Go! Take the 2026 Go Developer Survey

server

package module
v0.1.0-rc.5 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: Apache-2.0 Imports: 44 Imported by: 0

Documentation

Overview

Package server serves a tinystore.Store to other processes through any byte stream, as research's design/server.md designed it: a sidecar's clients in Bun and Python on the same machine and a remote server's alike. A handler turns a message into an engine's call and its answer into a message; claims, leases, group commits, snapshots and bounds stay the engines'. The bytes are server/wire, laid out in docs/wire.md.

server.go    New, Serve, ServeConn, Close: the server, its limits and its engines
session.go   a connection: its handshake, its reader, GOAWAY, silence
stream.go    a stream, an upload's inbox, and a call as its handler answers it
workers.go   the goroutines that run a connection's calls, and a call's one end
errors.go    an engine's error as a code and the item it names
listen.go    Listen: Unix sockets, TCP and TLS; pipe.go: Windows named pipes
local.go     Publish: the directory's shared sidecar and its SERVE; Share: a program's own store
tokens.go    the tokens a remote connection is let in with
handles.go   the numbers open calls answer with
bodies.go    the pools frame bodies are read into
datasql.go   the check a data connection's SQL passes; sqltokens.go: SQLite's tokens
methods.go   every method, by its number; clock.go: a test's clock, which server.clock moves
kv.go, jobs.go, jobs_work.go, blobs.go, records.go, metrics.go, sql.go: each engine's handlers

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Share

func Share(ctx context.Context, store *tinystore.Store, options Options) (stop func() error, err error)

Share serves a program's own store to the other processes of its machine while the program runs: it publishes the store as Publish does and serves whoever finds it there, the tinystore command, an agent over MCP, and Bun and Python programs alike. options carries the engines the program opened, since each opens once a store.

stop, err := server.Share(ctx, store, server.Options{KV: state})
if err != nil {
	return err
}
defer stop()

ctx bounds publishing alone. stop removes SERVE and closes the server, giving the streams running ten seconds to finish before it cancels them, and waits for every connection to end; it comes before the store's Close.

Types

type Clock

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

Clock is the time a store runs on in a test, which an admin's server.clock sets or moves forward: tinystore serve --stdio --clock gives one to the private server an SDK starts for a test. A server without one runs on the system's time and refuses the call.

clock := server.NewClock(start)
store, err := tinystore.Open(ctx, dir, tinystore.Options{Clock: clock.Now})
srv, err := server.New(store, server.Options{Clock: clock})

func NewClock

func NewClock(start time.Time) *Clock

NewClock is a clock that reads start until it is moved.

func (*Clock) Now

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

Now is the clock's time, for tinystore.Options.Clock.

type Listener

type Listener interface {
	Accept() (io.ReadWriteCloser, error)
	Close() error
	Addr() string // the endpoint, as SERVE names it
	Remote() bool
}

Listener hands the server connections. Remote says they come from a network, and their HELLO must carry a token; a local one's permission is the file system's.

func Listen

func Listen(ctx context.Context, endpoint string, config *tls.Config) (Listener, error)

Listen listens at an endpoint:

unix:///srv/app/data/server/tinystore.sock   a Unix socket, local
pipe:tinystore-1f3a…                         a Windows named pipe, local
tcp://0.0.0.0:7443                           TCP, remote
tls://0.0.0.0:7443                           TCP with TLS, remote; config is its certificate

type Options

type Options struct {
	// Version is the server's, as WELCOME states it.
	Version string

	// Logger receives the server's own logs; nil takes the store's, labelled
	// engine=server.
	Logger *slog.Logger

	// Tokens let remote connections in, each with its capability; a local
	// connection needs none.
	Tokens Tokens

	// KV is the kv engine the program opened. When it is nil the server opens
	// it with KVOptions the first time a client asks, since an engine opens
	// once a store. The same holds for every engine below.
	KV             *kv.Store
	KVOptions      kv.Options
	Jobs           *jobs.Store
	JobsOptions    jobs.Options
	Blobs          *blobs.Store
	BlobsOptions   blobs.Options
	Records        *records.Store
	RecordsOptions records.Options
	Metrics        *metrics.Store
	MetricsOptions metrics.Options

	// Stop stops the program serving the store when an admin client asks it
	// to, by server.stop, once the server has answered; nil refuses the
	// request, since a program serving its own store decides when it stops.
	// It returns at once, and the program closes the server as it would.
	Stop func()

	// Sidecar says in SERVE that this is the directory's sidecar, which a
	// client of a newer release replaces with its own: tinystore serve --local
	// started for its clients, not a program's own server or a person's.
	Sidecar bool

	// Clock is the time the store runs on in a test, which an admin's
	// server.clock moves; the store must read it, through
	// tinystore.Options.Clock. Nil refuses the call: the system's time.
	Clock *Clock

	// SQL holds the databases the program opened, by name. A client's sql.open
	// of one checks the migrations it carries against those the file applied,
	// since a database opens once a store. The server opens any other name
	// itself, with the migrations the client carries.
	SQL map[string]*sqldb.DB

	// JobsIn holds the jobs stores the program opened In its databases, by the
	// database's name, as SQL holds the databases. A client's queue in one of
	// them lives there; the server opens any other itself, In the database of
	// that name, once a client has opened it.
	JobsIn map[string]*jobs.Store
}

type Server

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

Server serves one store to other processes, a sidecar's or a remote server's clients alike, through any byte stream.

func New

func New(store *tinystore.Store, options Options) (*Server, error)

New makes a server of store, which the caller keeps open for as long as it serves and closes after it.

func (*Server) Close

func (s *Server) Close(ctx context.Context) error

Close stops the listeners and tells every connection with a GOAWAY that the server is going: the streams running finish, a REQUEST that crossed the GOAWAY is answered unavailable, and each connection closes when its last stream ends. When ctx ends first the streams still running are cancelled.

func (*Server) Instance

func (s *Server) Instance() []byte

Instance is the sixteen random bytes WELCOME repeats, and SERVE names.

func (*Server) Publish

func (s *Server) Publish(ctx context.Context) (l Listener, unpublish func() error, err error)

Publish listens where the directory's shared sidecar is found and writes SERVE beside it, whole. The place is a Unix socket in <dir>/server/ or, on Windows, a named pipe named after the directory.

The store holds the directory's lock, so claiming server/ from it proves the directory is this server's to publish. The directory is its owner's alone.

unpublish removes SERVE and the socket. Serve closes the listener once the server closes.

func (*Server) Serve

func (s *Server) Serve(ctx context.Context, l Listener) error

Serve accepts connections from l and serves each. It returns nil when l closes, ctx ends or the server closes, and an error when l fails.

The connections it accepted go on until they end, until ctx ends, or until Close ends them.

func (*Server) ServeConn

func (s *Server) ServeConn(ctx context.Context, conn io.ReadWriteCloser, remote bool) error

ServeConn serves one connection until it ends or ctx ends, as a private child serves its parent's stdin and stdout. remote says it came from a network, and so it must carry a token.

The end of what the client sends drains the streams running and returns nil.

func (*Server) WaitIdle

func (s *Server) WaitIdle(ctx context.Context, idle time.Duration) error

WaitIdle returns once no connection has been open for idle, as a shared sidecar leaves when its clients have. It returns ctx's error if ctx ends first.

type Tokens

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

Tokens let remote connections in: a HELLO's token finds its capability.

func ParseTokens

func ParseTokens(text []byte) (Tokens, error)

ParseTokens reads a tokens file, a token a line with its capability first:

admin q1q0l3yZ3JvYw8g7oM2sYAq1q0l3yZ3JvYw8g7oM2sY
data  Zm9vYmFyYmF6cXV4Zm9vYmFyYmF6cXV4Zm9vYmFyYmE

A blank line, or one that begins with #, says nothing.

Directories

Path Synopsis
internal
client
Package client is the Go end of a connection, which the server's tests and measurements use: calls from many goroutines, each a stream of its own, and their answers in any order.
Package client is the Go end of a connection, which the server's tests and measurements use: calls from many goroutines, each a stream of its own, and their answers in any order.
flow
Package flow is how a connection's frames leave and what paces them, the same at the server and at a client.
Package flow is how a connection's frames leave and what paces them, the same at the server and at a client.
pipe
Package pipe serves and reaches a Windows named pipe; elsewhere a Unix socket is the local transport, and it has nothing to serve.
Package pipe serves and reaches a Windows named pipe; elsewhere a Unix socket is the local transport, and it has nothing to serve.
private
Package private makes a directory its owner's alone, as a local server's SERVE and socket need.
Package private makes a directory its owner's alone, as a local server's SERVE and socket need.
Package reach is how a program that does not hold a store reaches the server a directory's SERVE names, as an SDK does: a fresh challenge in its HELLO, and no call before the WELCOME's proof checks.
Package reach is how a program that does not hold a store reaches the server a directory's SERVE names, as an SDK does: a fresh challenge in its HELLO, and no call before the WELCOME's proof checks.
Package wire is the bytes a TinyStore server and its clients exchange over any byte stream, as docs/wire.md lays them out: frames, the MessagePack profile their bodies follow, the messages and the error codes.
Package wire is the bytes a TinyStore server and its clients exchange over any byte stream, as docs/wire.md lays them out: frames, the MessagePack profile their bodies follow, the messages and the error codes.

Jump to

Keyboard shortcuts

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