scriptguard

package
v1.137.1 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package scriptguard is what stops a managed-script run apart from the script's own logic, and what that stop is recorded as: the memory budget a run is measured against at every host call (#1861), and the cause a failed run is recorded under -- the script's, an upstream that did not answer, or the budget -- which decides whether running it again is expected to succeed (#1859).

It knows the Starlark value model, and nothing about runs, stores or workers: the engine in internal/platform/scriptrun calls into it at its host bindings. The waits the host makes on an upstream that asked it to come back later are internal/upstreamretry's.

Index

Constants

This section is empty.

Variables

View Source
var ErrMemoryBudget = errors.New("script exceeded its memory budget")

ErrMemoryBudget marks a run stopped for holding more memory than its budget.

View Source
var Fail = starlark.NewBuiltin("fail", func(
	thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple,
) (starlark.Value, error) {
	retryable := false
	rest := make([]starlark.Tuple, 0, len(kwargs))
	for _, kv := range kwargs {
		if name, _ := starlark.AsString(kv[0]); name != "retryable" {
			rest = append(rest, kv)
			continue
		}
		flag, ok := kv[1].(starlark.Bool)
		if !ok {
			return nil, fmt.Errorf("fail: retryable must be True or False, not %s", kv[1].Type())
		}
		retryable = bool(flag)
	}
	_, err := starlark.Call(thread, starlark.Universe["fail"], args, rest)
	// Call reports the universe's failure as an EvalError of its own frame;
	// the failure itself is what this builtin raises, so the backtrace the
	// author reads names one fail() call, as before.
	var evalErr *starlark.EvalError
	if errors.As(err, &evalErr) && evalErr.Unwrap() != nil {
		err = evalErr.Unwrap()
	}
	if retryable {
		return nil, NewTransientError(err)
	}
	return nil, err
})

Fail is Starlark's fail(*args, sep=" ") with one more keyword (#1935): retryable=True declares the failure temporary, so the run is recorded as retryable (cause transient) rather than as the script's own. Everything else is the universe's fail, unchanged, so a script that never passes retryable= fails exactly as it did.

Functions

func Cause

func Cause(err error) string

Cause is the cause a run that failed with err is recorded under: memory for a budget it exceeded, upstream for an upstream that was unavailable or answered the script's last call with a failure, transient for a failure the script declared temporary, and the script's own for every other failure the interpreter reports.

func FormatBytes

func FormatBytes(n int64) string

FormatBytes renders a size the way the budget is configured: "128 MiB".

func Size

func Size(v starlark.Value) int64

Size estimates the heap v holds, counting a container reached twice once.

Types

type LastUpstream added in v1.137.1

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

LastUpstream keeps whether the upstream answered a run's most recent tool call with a failure (#1935). The api gateway hands a script a 5xx as data, so a script that checks the status and calls fail() -- the only thing it can do -- fails because of that answer, and is recorded as the upstream's rather than told the next run fails the same way. The zero value holds none.

func (*LastUpstream) Attribute added in v1.137.1

func (l *LastUpstream) Attribute(err error, note func(string), keep ...error) error

Attribute returns err as the upstream's when the run's latest call was answered with a failure and err is otherwise the script's own, handing note the line the run's log records why; err unchanged otherwise. A limit a caller names in keep, a memory stop and a failure already classified keep theirs.

func (*LastUpstream) Clear added in v1.137.1

func (l *LastUpstream) Clear()

Clear records a latest call that got no upstream answer at all.

func (*LastUpstream) Note added in v1.137.1

func (l *LastUpstream) Note(tool string, out map[string]any)

Note records the answer to the run's latest tool call: a 5xx or 429 is kept, anything else clears what an earlier call left.

type Meter

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

Meter measures what one run holds against its budget and keeps the peak. It is used from the interpreter's goroutine only, at host calls.

func NewMeter

func NewMeter(budget int64) *Meter

NewMeter returns a meter for a run allowed budget bytes; zero or less sets no budget and still measures the peak.

func (*Meter) Called

func (m *Meter) Called(tool string)

Called counts one tool result the run was handed, for the refusal to say where its memory came from.

func (*Meter) Check

func (m *Meter) Check(thread *starlark.Thread, at string) error

Check measures what the thread holds at the host call named at, and refuses once it is over the budget. It walks the thread when the last walk is older than walkEvery, or when the last estimate plus what the process has allocated since could be over the budget. A nil meter measures nothing.

func (*Meter) Handed

func (m *Meter) Handed(thread *starlark.Thread, at string, result starlark.Value) error

Handed adds a value a host call is about to hand the script to the estimate, and refuses when it takes the run over its budget.

func (*Meter) Holding

func (m *Meter) Holding(n int64)

Holding records how much the run holds outside the interpreter, replacing the last figure. The figure is measured, not estimated, so it counts toward the peak.

func (*Meter) Peak

func (m *Meter) Peak() int64

Peak is the most the run was measured holding.

func (*Meter) Settle

func (m *Meter) Settle(globals starlark.StringDict) error

Settle measures what the module's globals hold when the script ends, so the peak includes what it built after its last host call, and refuses when that is over the budget: a run that ended holding more than it is allowed failed its budget as surely as one stopped at a host call.

type TransientError added in v1.137.1

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

TransientError is a failure the script declared temporary with fail(..., retryable=True) (#1935): its author knows the condition it stopped on is outside the script, such as data that has not arrived yet.

func NewTransientError added in v1.137.1

func NewTransientError(err error) *TransientError

NewTransientError marks the failure fail() raised as temporary.

func (*TransientError) Error added in v1.137.1

func (e *TransientError) Error() string

Error returns fail()'s own text, which is what the author reads.

func (*TransientError) Unwrap added in v1.137.1

func (e *TransientError) Unwrap() error

Unwrap returns the failure fail() raised.

type UpstreamError

type UpstreamError struct {
	// Tool is the tool the script called.
	Tool string
	// contains filtered or unexported fields
}

UpstreamError is a tool call that failed because the upstream it reached was unavailable: it timed out, dropped the connection, or could not be reached, or the run's deadline arrived while the host was waiting to retry it. The same call made later is expected to succeed, so a run it ends is recorded as retryable.

func NewUpstreamError

func NewUpstreamError(tool string, err error) *UpstreamError

NewUpstreamError wraps the failure of a call to tool as an upstream one.

func (*UpstreamError) Error

func (e *UpstreamError) Error() string

Error returns the tool's own failure text, which is what the author reads.

func (*UpstreamError) Unwrap

func (e *UpstreamError) Unwrap() error

Unwrap returns the failure the tool reported.

Jump to

Keyboard shortcuts

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