durable

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: 23 Imported by: 0

Documentation

Overview

Package durable relays one durable task invocation between the engine, reached through a link.DurableChannel, and a serverless endpoint, reached over an operator-dialed websocket. The socket is the invocation's single request: the core sends the assigned action as the first frame, forwards the endpoint's DurableTaskRequests to the engine and the engine's DurableTaskResponses back, and reads the outcome from the endpoint's final done frame. What an exit means depends on what the engine has already committed to (an acknowledged eviction, a reported error); outcome.go holds that table.

Every frame is one protojson v1.ServerlessDurableFrame (api-contracts/v1/serverless.proto), encoded and decoded through the contract package.

Index

Constants

View Source
const (
	// CloseEvicted follows a forwarded server_evict: the engine superseded the invocation.
	CloseEvicted = 4001
	// CloseShuttingDown means the operator is stopping; the engine re-delivers the task.
	CloseShuttingDown = 4002
	// CloseCancelled means the engine cancelled the task.
	CloseCancelled = 4003
	// CloseInvocationMismatch means a request carried another task id or invocation count.
	CloseInvocationMismatch = 4004
	// CloseForbiddenMessage means the endpoint sent a link-internal request
	// (register_worker, worker_status), a frame that is not a request or done, a done
	// frame whose output is not JSON, or a done frame with status evicted before the engine
	// acknowledged an eviction.
	CloseForbiddenMessage = 4005
	// CloseRequestInFlight means a second ack-bearing request was sent before the first
	// was acknowledged.
	CloseRequestInFlight = 4006
	// CloseTimeout means the endpoint's request timeout elapsed with no done frame.
	CloseTimeout = 4007
	// CloseUnresponsive means two consecutive pings went unanswered.
	CloseUnresponsive = 4008
	// CloseBackpressure means the endpoint fell more than sendQueueSize frames or
	// Params.MaxQueuedBytes behind.
	CloseBackpressure = 1013
	// CloseNormal is sent after a done frame.
	CloseNormal = 1000
	// CloseInternalError is sent when the engine side of the relay fails.
	CloseInternalError = 1011
)

Close codes the relay sends. The 4xxx codes are application-defined; 1013 is the standard "try again later" code, used for backpressure.

View Source
const (
	EvictionSourceEndpoint = "endpoint"
	EvictionSourceServer   = "server"
)

Eviction sources for the evictions_total metric.

Variables

View Source
var ErrNoSecret = errors.New("endpoint has no signing secret")

ErrNoSecret is returned when the endpoint has no signing secret to sign the upgrade with.

View Source
var ErrUpgradeHeadersTooLarge = errors.New("endpoint upgrade response headers exceeded the limit")

ErrUpgradeHeadersTooLarge is returned when the endpoint's upgrade response headers exceed Params.MaxUpgradeHeaderBytes. The handshake is parsed before the websocket frame limit applies, so this is the only bound on what an endpoint can make the operator allocate for the response.

Functions

This section is empty.

Types

type Kind

type Kind int

Kind is the class of a relay outcome.

const (
	// KindCompleted: the endpoint sent done with an output; report COMPLETED.
	KindCompleted Kind = iota + 1
	// KindFailed: report FAILED with Outcome.Error and Outcome.Retry.
	KindFailed
	// KindEvicted: the invocation was evicted by the endpoint or the engine; no terminal
	// event, the engine re-invokes when the awaited entry is satisfied.
	KindEvicted
	// KindCancelled: the engine cancelled the task; the CANCELLED event was already sent.
	KindCancelled
	// KindShutdown: the operator is stopping; no event, the engine re-delivers the task
	// when the worker goes away.
	KindShutdown
)

type NetDialer

type NetDialer interface {
	DialContext(ctx context.Context, network, addr string) (net.Conn, error)
}

NetDialer opens the TCP connection under the operator's SSRF policy. *safeclient.Sender satisfies it; tests use a plain net.Dialer against loopback.

type Outcome

type Outcome struct {
	Output         json.RawMessage
	Error          string
	EvictionSource string
	Kind           Kind
	CloseCode      int
	Retry          bool
}

Outcome is what one relayed invocation reports back.

func Run

func Run(ctx context.Context, p Params) Outcome

Run relays one invocation and returns its outcome. ctx is the delivery context: the endpoint's request timeout is expected to be applied to it by the caller; cancellation maps to KindCancelled or KindShutdown through Params.Cancelled.

type Params

type Params struct {
	Logger  *zerolog.Logger
	Dialer  NetDialer
	Channel link.DurableChannel
	Action  *contracts.AssignedAction

	// Cancelled reports, once ctx is done, whether the engine cancelled the task (close
	// 4003, no event: the CANCELLED event was already sent) as opposed to the operator
	// shutting down (close 4002, no event). nil means shutting down.
	Cancelled func() bool

	TriggerURL string
	Secret     string
	EndpointId string
	Namespace  string
	TaskId     string

	MaxFrameBytes int64

	// MaxUpgradeHeaderBytes bounds the endpoint's upgrade response head (status line and
	// headers); 64 KiB by default.
	MaxUpgradeHeaderBytes int64

	// MaxQueuedBytes bounds the encoded frames waiting for the endpoint, in addition to the
	// sendQueueSize frame count; crossing it closes the socket with CloseBackpressure. 16 MiB
	// by default. A single frame larger than the budget trips it on its own.
	MaxQueuedBytes int64

	PingInterval     time.Duration
	HandshakeTimeout time.Duration

	InlineWaitBudgetMs int32
	Invocation         int32

	// Insecure allows http trigger URLs (ws) and must only be set together with
	// safeclient's InsecureDestinations.
	Insecure bool
	// contains filtered or unexported fields
}

Params describes one invocation to relay. Channel is opened by the caller and closed by Run on every exit.

type UpgradeError

type UpgradeError struct {
	Status int
}

UpgradeError is returned when the endpoint answered the upgrade with something other than 101. Status is the HTTP status it sent.

func (*UpgradeError) Error

func (e *UpgradeError) Error() string

func (*UpgradeError) Retryable

func (e *UpgradeError) Retryable() bool

Retryable reports whether the refusal is transient by the same rule as non-durable responses: 5xx, 408, 425 and 429 are retried, other statuses are not.

Jump to

Keyboard shortcuts

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