client

package
v0.4.0-rc.1 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package client is the grant protocol from the caller's side: a client for Clone, Park, Release, Discard and Watch that turns the two miss outcomes into typed errors a consumer branches on. A consumer (a Knative activator, a container shim, a virtual node) calls Clone with the signed grant it holds; on DEFERRED_FALLBACK it takes its ordinary path (create the thing the slow way, or route to the home that holds the session's state), on SHED it waits retry_after and tries again. Nothing here knows which home it talks to.

Upload, Download and ListFiles move files into and out of a running fiber's workspace. A grant without a disk budget has no workspace, and its file calls fail with *NoWorkspace. A file over the budget fails with *QuotaExceeded.

Index

Constants

Variables

View Source
var ErrNotHandoff = errors.New("client: not a handoff fiber")

ErrNotHandoff means the fiber was not cloned under a HANDOFF grant, so it has no routing key. Dial its Endpoint directly.

View Source
var ErrSize = errors.New("client: the upload's reader does not match its size")

ErrSize means an upload's reader does not hold the size it declared, or the size is negative. fiberd never placed the file.

Functions

func NotFound

func NotFound(err error) bool

NotFound reports a Park, Release or file call on a fiber the home does not know, such as a prior epoch's fence or one already gone. For a file call it also reports a missing file. For Discard it reports a session the home does not know.

Types

type Client

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

Client talks to one home.

func Dial

func Dial(ctx context.Context, target string) (*Client, error)

Dial connects to a home's gRPC address in plaintext. It works only against a home started with -insecure-plaintext. Use DialTLS otherwise.

func DialTLS

func DialTLS(ctx context.Context, target string, cfg *tls.Config) (*Client, error)

DialTLS connects to a home over mutual TLS. cfg carries the home's CA and this caller's certificate. Grants bound to the key of that certificate work only on a connection that presents it.

func New

func New(conn *grpc.ClientConn) *Client

New wraps an existing connection (tests, bufconn).

func (*Client) Clone

func (c *Client) Clone(ctx context.Context, grantJWT, session string, deadline time.Duration, payload []byte) (Fiber, error)

Clone resolves session (empty: an anonymous fiber) under the grant, within deadline. Errors are *Shed, *Deferred, *TierGap or the raw gRPC error for anything else.

func (*Client) Close

func (c *Client) Close() error

func (*Client) Discard

func (c *Client) Discard(ctx context.Context, grantJWT, session string) error

Discard deletes a parked session's delta under the grant, on the home and in the delta registry. The home then forgets the session, so its next Clone is a CREATE. A running session is refused with InvalidArgument. Release its fiber instead. An unknown session is NotFound.

func (*Client) Download

func (c *Client) Download(ctx context.Context, fiberID, path string, offset uint64) (*FileReader, error)

Download opens one regular file of a running fiber's workspace for reading from offset. It waits for the first chunk, so a refusal comes from Download itself. The caller must Close the reader.

Errors are *NoWorkspace, or the raw gRPC error for anything else. NotFound reports an unknown fiber or a missing file.

func (*Client) ListFiles

func (c *Client) ListFiles(ctx context.Context, fiberID, dir string) ([]FileInfo, error)

ListFiles lists one directory of a running fiber's workspace, not recursively. An empty dir is the workspace itself. Errors are those of Download, and NotFound also reports a missing directory.

func (*Client) Park

func (c *Client) Park(ctx context.Context, fiberID string, sync bool) error

Park checkpoints the fiber; with sync the reply waits for the delta to be durable.

func (*Client) Release

func (c *Client) Release(ctx context.Context, fiberID string, discard bool) error

Release ends the fiber; with discard its session's parked delta goes too.

func (*Client) Upload

func (c *Client) Upload(ctx context.Context, fiberID, path string, size int64, r io.Reader, opts ...UploadOption) (FileInfo, error)

Upload writes one file of size bytes into a running fiber's workspace. path is relative to the fiber's /workspace. r must hold exactly size bytes, and Upload reads it to its end to check that. A nil r is empty. A reader that is short or long fails with ErrSize, and fiberd never places the file. The data goes in chunks of at most 1 MiB, and the file appears only once every byte arrived.

Errors are *NoWorkspace, *QuotaExceeded, ErrSize, r's own error, or the raw gRPC error for anything else. NotFound reports an unknown fiber.

func (*Client) Watch

func (c *Client) Watch(ctx context.Context, fn func(Status)) error

Watch streams status until ctx ends or the stream breaks; fn is called for every line.

type Deferred

type Deferred struct {
	Issuer        string
	PreferredHome string
	Reason        string
}

Deferred is the miss with the control plane healthy: the home cannot serve this clone (no capacity, expired grant, session too large to move) and the consumer takes its ordinary path. PreferredHome, when set, is where the session's parked state lives.

func (*Deferred) Error

func (e *Deferred) Error() string

type Fence

type Fence struct {
	GrantUID   string
	Epoch, Seq uint64
}

Fence is the fiber's incarnation.

func (Fence) String

func (f Fence) String() string

type Fiber

type Fiber struct {
	ID       string
	Endpoint string // a URL to dial as given (unix://..., tcp://...)
	// RoutingKey and ServerKeySHA256 are set only under a HANDOFF grant.
	// Reach such a fiber with DialHandoff.
	RoutingKey      string
	ServerKeySHA256 string
	Fence           Fence
	Kind            Kind
}

Fiber is what a successful Clone returns.

func (Fiber) DialHandoff

func (f Fiber) DialHandoff(ctx context.Context, cert tls.Certificate) (*tls.Conn, error)

DialHandoff opens a TLS connection to a handoff fiber through its home's router. cert must be the certificate the grant is bound to, the same one used on the control API. The fiber refuses any other. The fiber's key must match ServerKeySHA256 (handoff.ErrKeyMismatch).

type FileInfo

type FileInfo struct {
	// Path is relative to the fiber's /workspace.
	Path string
	Size uint64
	// Mode holds the permission bits only. Directory tells a directory
	// apart.
	Mode      fs.FileMode
	Directory bool
	// SHA256 is the content's digest. Only Upload's reply sets it.
	SHA256 []byte
}

FileInfo describes one entry of a fiber's workspace.

type FileReader

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

FileReader reads a file Download opened. Read returns io.EOF at the file's end. Close ends the stream and may run while a Read waits.

func (*FileReader) Close

func (f *FileReader) Close() error

Close ends the download. Calling it again does nothing.

func (*FileReader) Info

func (f *FileReader) Info() FileInfo

Info describes the file, as the first chunk carried it.

func (*FileReader) Read

func (f *FileReader) Read(p []byte) (int, error)

Read serves the chunks' data in order. After Close it returns fs.ErrClosed.

type Kind

type Kind = grantv1.CloneKind

Kind is how a Clone was served.

type NoWorkspace

type NoWorkspace struct{ Reason string }

NoWorkspace: a file call reached a fiber whose grant has no workspace, since its disk_budget_bytes is zero. Not a miss and not a tier gap.

func (*NoWorkspace) Error

func (e *NoWorkspace) Error() string

type QuotaExceeded

type QuotaExceeded struct{ Reason string }

QuotaExceeded: the file does not fit the workspace's disk budget or its entry limit. Not a shed, so retrying the same upload fails again.

func (*QuotaExceeded) Error

func (e *QuotaExceeded) Error() string

type Shed

type Shed struct {
	RetryAfter time.Duration
	Issuer     string
	Reason     string
}

Shed is the miss that says to retry here later: the control plane is unreachable, or the home is under pressure (memory, tasks, the clone rate limit). Reason is the home's own. The caller waits and retries; it does not fall back, because the fallback path needs the same control plane or adds load where there is already too much.

func (*Shed) Error

func (e *Shed) Error() string

type Status

type Status struct {
	GrantUID                string
	Running, Parked, Pooled uint32
	WUsedBytes              uint64
	Latest                  Fence
}

Status is one grant's line of the Watch stream.

type TierGap

type TierGap struct{ Reason string }

TierGap: the grant or the parked session needs a tier this home does not offer. Not a miss; the grant was placed on the wrong home.

func (*TierGap) Error

func (e *TierGap) Error() string

type UploadOption

type UploadOption func(*uploadOptions)

UploadOption sets an optional field of an upload's header.

func WithMode

func WithMode(mode fs.FileMode) UploadOption

WithMode sets the file's permission bits. Without it the file is 0644.

func WithSHA256

func WithSHA256(sum []byte) UploadOption

WithSHA256 has fiberd check the content against sum before the file appears.

Jump to

Keyboard shortcuts

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