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 ¶
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 StatusCancelled = "cancelled" // an administrator cancelled the job while it ran (the worker stopped the run) )
Result statuses.
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 ¶
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 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
// Progress says the run is an async job's attempt: the runner reports its
// steps live with Token (PUT /v1/{realm}/_job/steps).
Progress bool `json:"progress,omitempty"`
}
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.
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 ¶
New prepares the working directory: the runner and the JS client it imports, and the bundle cache. It refuses to run where !Supported.
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 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"`
// Steps are what the function reported with ctx.step and ctx.progress, from
// the result line. A run that was killed sends none; for a job, backd has
// the last it was sent live.
Steps []Step `json:"steps,omitempty"`
StepsOmitted int `json:"steps_omitted,omitempty"`
}
Result is how an invocation ended.
type Step ¶ added in v0.8.0
type Step struct {
N int `json:"n"`
Name string `json:"name"`
Status string `json:"status"` // running, done, failed, timed_out or cancelled
StartedAt time.Time `json:"started_at"`
EndedAt *time.Time `json:"ended_at"`
DurationMS *int64 `json:"duration_ms"`
Current float64 `json:"current"`
Total *float64 `json:"total"`
Message *string `json:"message"`
UpdatedAt time.Time `json:"updated_at"`
}
Step is one step a function reported (ctx.step), with how far it got.
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.