client

package
v0.0.21 Latest Latest
Warning

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

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

Documentation

Overview

Package client is the client tier: the one decoration every outbound client (an SDK, a datastore, an HTTP API) runs its operations through. Tier orders the layers; the decoration config (decoration.clients, built by decorate.Decorations) switches and tunes them per client and per operation; Base, built from the client's contract, gives its decorated wrapper typed per-operation helpers as generic methods; and Kinds is each family's backend table.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Call added in v0.0.12

func Call[In, Out, Opt any](
	ctx context.Context,
	b Base,
	op string,
	fn func(context.Context, *In, ...func(*Opt)) (*Out, error),
	in *In,
	opts ...func(*Opt),
) (*Out, error)

Call runs one SDK operation of the common `(ctx, *In, ...func(*Opt)) (*Out, error)` shape through b as the operation op, retried when the tier retries.

func CallOnce added in v0.0.12

func CallOnce[In, Out, Opt any](
	ctx context.Context,
	b Base,
	op string,
	fn func(context.Context, *In, ...func(*Opt)) (*Out, error),
	in *In,
	opts ...func(*Opt),
) (*Out, error)

CallOnce runs one SDK operation like Call, without retry, for a call whose replay may repeat its effect.

func Output added in v0.0.17

func Output(res interfaces.CmdResult, what string) ([]byte, error)

Output returns a command's stdout, or a coded error saying what failed with the tail of its stderr: CodeUnavailable when the command could not start (exit -1), else CodeUpstream.

func SplitNUL added in v0.0.17

func SplitNUL(out []byte) []string

SplitNUL splits NUL-delimited command output (`git … -z`) into its non-empty fields.

func Tier

func Tier() decorate.Tier

Tier is the client decoration tier, outermost first: the bulkhead bounds the calls in flight, retry replays a transient failure through the breaker, and each attempt gets its own deadline, client span, metrics and log line.

Types

type Backend

type Backend[C, D, T any] = func(ctx context.Context, cfg C, deps D) (T, error)

Backend builds one Kind of a family from its Config C and Deps D into its interface T; ctx bounds any I/O the backend does to construct.

type Base

type Base struct {
	// Subject runs the client's operations; it supplies Name, Exec and ExecOnce.
	decorate.Subject
}

Base runs one client's operations through the client tier: each operation is one method of the client's contract, decorated as the client's name plus the method's snake_case name. Its embedded Subject supplies Name, Exec (an idempotent operation, retried when the tier retries) and ExecOnce (one that must never be replayed); Do, DoOnce, Stream and Open cover the rest. The zero Base runs every operation undecorated.

func NewBase

func NewBase[C any](
	decs decorate.Decorations,
	name string,
	opts ...Option,
) (Base, error)

NewBase returns the Base for the client named name whose operations are the methods of its contract C, decorated from decs: the client as the client-tier component name, and each operation op as name+"."+op. A C that is not an interface, or a decoration that fails to resolve, is an error.

func NewWireBase added in v0.0.14

func NewWireBase(decs decorate.Decorations, name string, opts ...Option) (Base, error)

NewWireBase returns the Base for the client named name whose operations are wire-level names known only per call (an RPC procedure, an HTTP route, a job kind): every operation runs on the client's own chain, labeled by its name, so the config tunes the client as a whole.

func (Base) Do

func (b Base) Do(ctx context.Context, op string, fn func(context.Context) error) error

Do runs the error-only idempotent operation op.

func (Base) DoOnce

func (b Base) DoOnce(
	ctx context.Context,
	op string,
	fn func(context.Context) error,
) error

DoOnce runs the error-only operation op without the retry layer.

func (Base) Open

func (b Base) Open[R any](
	ctx context.Context,
	op string,
	open func(context.Context) (R, error),
) (R, error)

Open opens a long-lived stream as the operation op, bounding only the open: the client's timeout caps how long open may take, while the stream it returns lives on ctx with no deadline of the client's (a generation stream can outlast any call budget). The open is decorated (never retried); an open that overruns is abandoned — its context canceled — and returned as CodeTimeout.

func (Base) Stream

func (b Base) Stream[R any](
	ctx context.Context,
	op string,
	open func(context.Context) (R, error),
) (stream R, release func(), err error)

Stream opens a stream as the operation op. The open is decorated (never retried); the operation's timeout bounds the stream's whole life, so the returned release must be called when the stream is closed. On error release is already done.

type Kind

type Kind string

Kind names one backend of a client family, as written in config.

const KindStub Kind = "stub"

KindStub is the zero-infrastructure backend a family ships so its graph boots without I/O.

type Kinds

type Kinds[C, D, T any] struct {
	// Backends maps each Kind to its constructor.
	Backends map[Kind]Backend[C, D, T]

	// Decorate wraps a backend in the client tier as the client named name, its Base
	// built from decs with opts (client.NewBase).
	Decorate func(base T, decs decorate.Decorations, name string, opts ...Option) (T, error)

	// Options shape the family's Base (Producer for a publisher).
	Options []Option

	// Family names the client family ("cache", "lock", …).
	Family string

	// Default is the Kind an empty config selects.
	Default Kind

	// AtMostOnce lists the kinds whose operations are at-most-once (a Redis PUBLISH): a
	// retry could repeat a delivery, so Build never retries them whatever the config says.
	AtMostOnce []Kind
}

Kinds is a client family's backend table: Family labels its errors and names the client in the tier, Default is the backend an empty Kind selects, Backends builds each Kind from the family's Config C and Deps D into its interface T, and Decorate runs a built backend through the client tier.

func (Kinds[C, D, T]) Build

func (k Kinds[C, D, T]) Build(
	ctx context.Context,
	kind Kind,
	cfg C,
	deps D,
	decs decorate.Decorations,
	name string,
) (T, error)

Build builds the backend kind names and runs it through the client tier as the client named name (Family when empty), one chain per method of T from decs; an AtMostOnce kind gets no retry.

func (Kinds[C, D, T]) New

func (k Kinds[C, D, T]) New(ctx context.Context, kind Kind, cfg C, deps D) (T, error)

New builds the backend kind names (Default when empty); ctx bounds any I/O the backend does to construct (an SDK config load). An unknown kind is CodeInvalidInput naming the family's known kinds.

type Option added in v0.0.14

type Option func(*options)

Option shapes how a Base decorates its client.

func AtMostOnce added in v0.0.14

func AtMostOnce() Option

AtMostOnce never retries the client's operations, whatever the config says: a retry could repeat a delivery (a Redis PUBLISH).

func Handler added in v0.0.14

func Handler() Option

Handler decorates a consumer's message handlers: observed (in consumer spans) and bounded, never retried or broken — the broker's redelivery is the retry, and one poison message must not trip the others.

func Producer added in v0.0.14

func Producer() Option

Producer decorates a message publisher: the client tier with producer spans, since each operation sends a message to a broker.

Jump to

Keyboard shortcuts

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