executor

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Overview

Package executor runs server-side functions: `backd executor` is a supervisor that runs each invocation in its own Deno process, with only the function's permissions and limits, and returns its output.

It never reads CONFIG_DIR or MongoDB. backd sends it an invocation (the bundle's hash and URL, limits, network allowlist and an envelope with the input, caller, secrets and callback token); it fetches the bundle from backd by hash, runs it through runner.js and reports the result.

Index

Constants

View Source
const (
	StatusOK            = "ok"
	StatusFunctionError = "function_error" // the function threw ctx.error(4xx, …)
	StatusError         = "error"          // the function threw anything else
	StatusTimeout       = "timeout"
	StatusMemory        = "memory"
	StatusCPU           = "cpu"
	StatusCrash         = "crash"            // the process ended without a result
	StatusOutputTooBig  = "output_too_large" // more than max_output
	StatusBusy          = "busy"             // the executor is at its process limit
	StatusBundle        = "bundle"           // the bundle couldn't be fetched or verified
)

Result statuses.

View Source
const Supported = true

Supported reports whether this system can enforce a function's limits (CPU time, resident memory, one process group to kill). Only Linux can.

Variables

View Source
var ErrUnsupportedPlatform = errors.New("the functions executor runs only on Linux: it needs process limits and /proc, which other systems don't have")

ErrUnsupportedPlatform means this system can't enforce a function's limits.

Functions

This section is empty.

Types

type Bundle

type Bundle struct {
	SHA256 string `json:"sha256"`
	URL    string `json:"url"`
}

Bundle names a function's bundle: backd serves it at URL.

type Callback

type Callback struct {
	URL        string `json:"url"`
	Realm      string `json:"realm"`
	Database   string `json:"database,omitempty"` // the function's own database, for ctx.call
	Token      string `json:"token,omitempty"`
	AdminToken string `json:"admin_token,omitempty"`
	Email      bool   `json:"email,omitempty"` // ctx.email.send
}

Callback is how the function reaches backd: ctx.db with Token (as the caller), ctx.admin.db with AdminToken (functions with admin: true).

type Client

type Client struct {
	URL   string // the executor, e.g. http://executor:9100
	Token string // shared secret (BACKD_EXECUTOR_TOKEN)
	HTTP  *http.Client
}

Client calls an executor: backd's side of POST /invoke.

func (*Client) Health

func (c *Client) Health(ctx context.Context) error

Health checks the executor answers.

func (*Client) Invoke

func (c *Client) Invoke(ctx context.Context, req InvokeRequest) (Result, error)

Invoke runs req on the executor. An error means the executor couldn't be reached or refused the request; how the function ended is in Result.

type Config

type Config struct {
	Deno         string // the deno binary; default "deno"
	Dir          string // writable working directory (runner, bundle cache)
	Token        string // shared with backd: authenticates both directions
	MaxProcesses int    // function processes at once; default 64
	// Proxy is backd egress's base URL (e.g. http://backd-egress:3128), set
	// as HTTP(S)_PROXY for function processes with a per-invocation token
	// (EgressKey) embedded as its credentials, scoped to that call's
	// allowed hosts. Both empty: functions get no outbound network at all
	// beyond what --allow-net itself permits on this host.
	Proxy     string
	EgressKey []byte
	// Metrics counts runs; nil turns it off.
	Metrics *metrics.Metrics
	Log     *slog.Logger
	HTTP    *http.Client // for bundle fetches
}

Config configures an Executor.

type Envelope

type Envelope struct {
	// Mode tells the runner how to shape ctx and interpret the
	// handler's return value: "sync"/"async" use Input/Output; "webhook"
	// uses Webhook/the Result's Webhook field instead.
	Mode    string            `json:"mode,omitempty"`
	Input   json.RawMessage   `json:"input,omitempty"`
	Webhook *WebhookRequest   `json:"webhook,omitempty"`
	User    json.RawMessage   `json:"user,omitempty"`
	Secrets map[string]string `json:"secrets,omitempty"`
	// Mask lists values that must never appear in the function's logs or
	// error message (such as a token in a link), without being given to it
	// as secrets: the executor replaces them like it does secrets' values.
	Mask           []string  `json:"mask,omitempty"`
	Callback       *Callback `json:"callback,omitempty"`
	IdempotencyKey string    `json:"idempotency_key,omitempty"`
	RequestID      string    `json:"request_id,omitempty"`
}

Envelope is what the function's process receives on stdin.

type Executor

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

Executor runs invocations.

func New

func New(cfg Config) (*Executor, error)

New prepares the working directory: the runner and the JS client it imports, and the bundle cache. It refuses to run where !Supported.

func (*Executor) Handler

func (e *Executor) Handler() http.Handler

Handler serves POST /invoke (with the token) and GET /healthz.

func (*Executor) Invoke

func (e *Executor) Invoke(ctx context.Context, req InvokeRequest) Result

Invoke runs one invocation to its end. ctx ending (the caller went away) kills the function.

type FunctionError

type FunctionError struct {
	Status  int             `json:"status"`
	Code    string          `json:"code"`
	Message string          `json:"message"`
	Details json.RawMessage `json:"details,omitempty"`
}

FunctionError is an error the function returns to its caller.

type InvokeRequest

type InvokeRequest struct {
	Function  string   `json:"function"` // <realm>/<database>/<name>, for logs
	Bundle    Bundle   `json:"bundle"`
	TimeoutMS int64    `json:"timeout_ms"`
	MemoryMB  int64    `json:"memory_mb"` // V8 heap
	MaxOutput int64    `json:"max_output"`
	Network   []string `json:"network,omitempty"` // host or host:port
	Envelope  Envelope `json:"envelope"`
}

InvokeRequest is one invocation, sent by backd.

type LogLine

type LogLine struct {
	Level string `json:"level"`
	Line  string `json:"line"`
}

LogLine is one line the function logged, secrets masked.

type Result

type Result struct {
	Status        string           `json:"status"`
	Output        json.RawMessage  `json:"output,omitempty"`
	Webhook       *WebhookResponse `json:"webhook,omitempty"`
	FunctionError *FunctionError   `json:"function_error,omitempty"`
	// Message explains other failures, for backd's logs only (it may hold
	// a stack trace); callers never see it.
	Message    string    `json:"message,omitempty"`
	Logs       []LogLine `json:"logs,omitempty"`
	DurationMS int64     `json:"duration_ms"`
}

Result is how an invocation ended.

type WebhookRequest

type WebhookRequest struct {
	Body    string      `json:"body"`
	Headers http.Header `json:"headers,omitempty"`
}

WebhookRequest is a webhook call's raw body and headers (roadmap F13), for a function to verify its sender's signature itself. The body is treated as UTF-8 text: real-world webhook senders (Stripe, GitHub, and similar) all send JSON.

type WebhookResponse

type WebhookResponse struct {
	Status  int               `json:"status"`
	Body    string            `json:"body"`
	Headers map[string]string `json:"headers,omitempty"`
}

WebhookResponse is a webhook function's own answer to its caller (roadmap F13): unlike sync/async, the function sets the HTTP status and body itself, not just a JSON value.

Jump to

Keyboard shortcuts

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