grpclink

package
v0.106.8-alpha.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package grpclink is the out-of-process Link: registrations are OperatorSessions opened over the engine's OperatorService with a per-tenant API token from a TenantTokenExchange.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoToken = link.ErrNoToken

ErrNoToken is returned by an exchange for a tenant it does not serve. It is the link package's sentinel so the core can match it without depending on grpclink.

Functions

This section is empty.

Types

type ClientFactory

type ClientFactory func(token string) (client.Client, error) //nolint:staticcheck // see import

ClientFactory builds the engine client for one token. The default derives the gRPC address and TLS settings from the token's claims and HATCHET_CLIENT_* environment, like the SDK.

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

Link caches one engine client per tenant. The token is asked from the exchange on every Open so a rotated token replaces the cached client, and the client is closed when it is replaced or when the core reports the tenant is no longer served, after every registration for the tenant is closed.

func New

func New(exchange TenantTokenExchange, opts Options) *Link

New builds a Link over exchange.

func (*Link) Open

func (g *Link) Open(ctx context.Context, tenantId uuid.UUID, opts link.OpenOpts) (link.Registration, error)

Open implements link.Link. An Unauthenticated connect drops the cached client and asks the exchange once more, so a token rotated between two Opens is used without waiting for the exchange's own reload. The initial action set is streamed to the engine right after the connect and flushed before the registration is returned; the session keeps it as the desired set and replays it when a reconnect does not resume the worker.

func (*Link) ReleaseTenant

func (g *Link) ReleaseTenant(tenantId uuid.UUID)

ReleaseTenant implements link.TenantReleaser.

type LocalExchange

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

LocalExchange reads tokens from a YAML file and reloads it when the file or any token_file it references changes. The mtimes are polled by a background goroutine so a rotated file or mounted secret is picked up without a restart; a reload that fails keeps the previous mapping and is logged when a logger is configured.

func NewLocalExchange

func NewLocalExchange(path string, opts ...LocalExchangeOpt) (*LocalExchange, error)

NewLocalExchange loads path once, failing on a missing or malformed file, and starts the mtime poller. Close stops it.

func (*LocalExchange) Close

func (e *LocalExchange) Close()

Close stops the mtime poller. Token keeps answering from the last loaded mapping.

func (*LocalExchange) Reload

func (e *LocalExchange) Reload() error

Reload re-reads the file and every token_file it references unconditionally.

func (*LocalExchange) Token

func (e *LocalExchange) Token(_ context.Context, tenantId uuid.UUID) (string, error)

Token implements TenantTokenExchange.

type LocalExchangeOpt

type LocalExchangeOpt func(*LocalExchange)

LocalExchangeOpt configures NewLocalExchange.

func WithLogger

func WithLogger(l *zerolog.Logger) LocalExchangeOpt

WithLogger reports reload failures; tokens are never logged.

func WithPollInterval

func WithPollInterval(d time.Duration) LocalExchangeOpt

WithPollInterval overrides how often the files' mtimes are checked.

type Options

type Options struct {
	Logger *zerolog.Logger

	// NewClient replaces the default client factory; tests inject a fake.
	NewClient ClientFactory

	// OperatorName is the OperatorService operator name every registration connects as. The
	// engine upserts one operator row per tenant by this name.
	OperatorName string
}

Options configures a Link.

type StaticExchange

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

StaticExchange serves a single tenant from one token, the tenant being the token's sub claim. It backs the HATCHET_CLIENT_TOKEN fallback for local development and tests.

func NewStaticExchange

func NewStaticExchange(token string) (*StaticExchange, error)

NewStaticExchange parses the tenant id out of token's sub claim.

func (*StaticExchange) TenantId

func (s *StaticExchange) TenantId() uuid.UUID

TenantId is the single tenant the exchange serves.

func (*StaticExchange) Token

func (s *StaticExchange) Token(_ context.Context, tenantId uuid.UUID) (string, error)

Token implements TenantTokenExchange.

type TenantTokenExchange

type TenantTokenExchange interface {
	// Token returns the tenant's token, or ErrNoToken when the tenant is not served.
	Token(ctx context.Context, tenantId uuid.UUID) (string, error)
}

TenantTokenExchange resolves the API token the link uses to register as a tenant. The database never stores tokens; every deployment plugs in its own source.

Jump to

Keyboard shortcuts

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