runtime

package
v0.11.1 Latest Latest
Warning

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

Go to latest
Published: Nov 5, 2026 License: BSD-3-Clause Imports: 17 Imported by: 0

Documentation

Overview

Package runtime is linked into every compiled notebook. The kernel starts the notebook's binary as a worker and drives it through Serve: it asks the worker to run a cell, to hand over the value of a notebook variable, or to take one back after a rebuild, so that cells whose code and inputs did not change are not run again.

The protocol is one JSON object per line on the worker's standard input and output. What a cell prints goes to a pipe of its own, so it can never be mistaken for a reply.

Index

Constants

View Source
const ExitMemory = 70

ExitMemory is the exit status of a worker that went over its limit: the kernel reports it as the cell's failure.

View Source
const MemoryEnv = "NOTEBOOK_MEMORY_LIMIT"

MemoryEnv is the environment variable through which the kernel gives a worker its memory limit, in bytes (Options.CellMemory).

View Source
const RLimitsEnv = "NOTEBOOK_R_LIMITS"

RLimitsEnv is the environment variable through which the kernel gives a worker the limits of its R session (Options.R): "alloc,steps,timeout", the bytes of vector storage and the calls one cell may use, and its time in nanoseconds; 0 is no bound.

View Source
const SessionFile = "(irb)"

SessionFile is the file name a session's inputs are evaluated under, as irb's are: backtraces read (irb):3.

Variables

View Source
var DefaultRLimits = RLimits{MaxAlloc: 512 << 20, MaxSteps: 50_000_000, Timeout: 30 * time.Second}

DefaultRLimits are the limits a kernel gives its R cells when it is not told others. A cell that needs more says so: Options.R.

  • 512 MiB of vectors is a 64-million-element numeric vector, the longest the session allows (MaxVector), a matrix of 8000 x 8000, or 64 passes over a 1-million-element vector that each make a new one. The total counts garbage too, so the heap a cell holds at once is at most this.
  • 50 million calls is 12 to 16 million iterations of a loop like s <- s + i (3 to 4 calls each), so a runaway loop ends on the steps, the same on every machine, and a cell that is merely slow (a simulation of 10 million iterations) still finishes.
  • 30 seconds is a notebook cell a person is waiting for. It is also the only bound on a loop that catches the step limit's own error (repeat tryCatch(…, error = function(e) NULL)), which R code can.

Functions

func Bundle

func Bundle(v any) map[string][]byte

Bundle returns the MIME bundle of a value: its own when it implements Displayer, else its fmt %v text. A Displayer without text/plain (a figure that is only SVG and PNG) gets its type, <*plot.Figure>, rather than the %v of its innards.

func Decode

func Decode(ptr any, data []byte) error

Decode is the inverse of Encode.

func Encode

func Encode(ptr any) ([]byte, error)

Encode encodes the value ptr points to: nil as nil, a value with its own MarshalBinary with it, anything else with gob when every field it can hold is exported (gob would silently drop the others). Anything else is an error, which makes the value volatile.

func Serve

func Serve(p Program)

Serve answers the kernel until it says exit or closes the input.

func ServeInterpreter added in v0.5.0

func ServeInterpreter(open func(out, errOut io.Writer) Interpreter)

ServeInterpreter is the main of a session's worker: it answers the kernel's "eval" and "complete" requests with the interpreter open returns until the kernel says exit or closes the input, and ends the process at once when the input closes in the middle of an evaluation (the kernel is gone). What the interpreter prints, through out and errOut, is sent to the kernel as it is printed, ahead of the reply that ends the input. What the process writes to its standard output otherwise goes to its standard error, which the kernel shows; and the interpreter reads an empty standard input: the worker's own two are the protocol.

Types

type Cell

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

Cell is handed to each compiled cell; the generated code calls Show with the cell's final expression.

func (*Cell) Note added in v0.3.0

func (c *Cell) Note(name, value string)

Note records a fact about the cell for the kernel: the Go type a Ruby variable has now, which the next program declares it with.

func (*Cell) Result

func (c *Cell) Result(v any, err error)

Result shows v, the value of a call that also returned an error, or, when err is not nil, fails the cell with it, so the cells that read this one do not run on a value that is not there.

func (*Cell) Show

func (c *Cell) Show(vs ...any)

Show records the display of each value. A nil interface — the nil error of a call run for its effect — shows nothing.

type CellError added in v0.3.0

type CellError interface {
	CellError() string
}

CellError is implemented by a panic value that is a cell's own failure, reported as it is rather than with the stack of the worker: a Ruby exception at its line in the notebook, a deferred cell.

type Deferred added in v0.3.0

type Deferred string

Deferred fails a cell that cannot be compiled yet, with the reason.

func (Deferred) CellError added in v0.3.0

func (d Deferred) CellError() string

CellError is the reason.

type Displayer

type Displayer interface {
	Display() map[string][]byte
}

Displayer is implemented by values that know how to show themselves: the result maps a MIME type ("text/plain", "text/html", "image/svg+xml", "image/png", ...) to the bytes of that representation.

type Interpreter added in v0.5.0

type Interpreter interface {
	// Eval evaluates src, which starts at line of file, and returns its
	// value's inspect and, for a value that shows itself (a figure), its MIME
	// bundle. An error that has a Class method names the exception.
	Eval(src, file string, line int) (inspect string, display map[string][]byte, err error)
	// Complete returns the completions of the word before the cursor.
	Complete(target string) []string
}

Interpreter evaluates the inputs of an interactive session (notebook irb) one at a time, as irb does. go-scikit/ruby's cells.Session is one.

type Program

type Program struct {
	// Cells holds the compiled cells by their index among the notebook's
	// code cells; a cell that defines nothing and shows nothing still has
	// an entry.
	Cells []func(*Cell)

	// Vars maps each notebook variable to a pointer to it.
	Vars map[string]any
}

Program is what the generated main hands to Serve.

type RLimits added in v0.11.0

type RLimits struct {
	// MaxAlloc is the bytes of vector storage one cell may allocate, in total
	// over its life, not at one time: a loop that grows a vector with c(x, i)
	// allocates n²/2 elements to hold n.
	MaxAlloc int
	// MaxSteps is the number of calls one cell may evaluate.
	MaxSteps int
	// Timeout is how long one cell may run.
	Timeout time.Duration
}

RLimits bound what one R cell may use. go-embedded-r bounds nothing but the depth of the evaluation and the length of a vector unless it is told to, and a notebook may come from anyone, so a worker with R cells is always given all three.

func ParseRLimits added in v0.11.0

func ParseRLimits(env string) RLimits

ParseRLimits reads the value of RLimitsEnv. An empty or malformed value is the defaults: a worker is never left without bounds because its environment was wrong.

func (RLimits) Env added in v0.11.0

func (l RLimits) Env() string

Env is the setting of RLimitsEnv for these limits, where a zero field takes its default and a negative one means no bound.

type Reply

type Reply struct {
	Cell    int                 `json:"cell,omitempty"`
	Name    string              `json:"name,omitempty"`
	Output  string              `json:"output,omitempty"`  // what the cell printed
	Display []map[string][]byte `json:"display,omitempty"` // what it showed
	Error   string              `json:"error,omitempty"`   // a panic, with its stack
	Took    time.Duration       `json:"took,omitempty"`    // how long the cell ran, in the worker
	Notes   map[string]string   `json:"notes,omitempty"`   // what the cell noted (Cell.Note)
	Data    []byte              `json:"data,omitempty"`    // an encoded value
	// Volatile reports a value that cannot be encoded (a func, a channel,
	// unexported state): the cell that makes it has to run again instead.
	Volatile bool `json:"volatile,omitempty"`

	// For a session's worker (ServeInterpreter): More marks a reply that only
	// carries Output, printed while the input runs, before the reply that
	// ends it. Inspect is the input's value as irb shows it, Class the
	// exception's class when it raised, Candidates the completions of a word.
	More       bool     `json:"more,omitempty"`
	Inspect    string   `json:"inspect,omitempty"`
	Class      string   `json:"class,omitempty"`
	Candidates []string `json:"candidates,omitempty"`
}

Reply answers a Request.

type Request

type Request struct {
	Op   string `json:"op"` // "run", "get", "set" or "exit"; "eval" or "complete" to a session's worker
	Cell int    `json:"cell,omitempty"`
	Name string `json:"name,omitempty"`
	Data []byte `json:"data,omitempty"`

	// Source is the input to evaluate, or the word to complete, and Line the
	// line it starts at in the session (ServeInterpreter).
	Source string `json:"source,omitempty"`
	Line   int    `json:"line,omitempty"`
}

Request is a command from the kernel.

Jump to

Keyboard shortcuts

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