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
- Variables
- func Bundle(v any) map[string][]byte
- func Decode(ptr any, data []byte) error
- func Encode(ptr any) ([]byte, error)
- func Serve(p Program)
- func ServeInterpreter(open func(out, errOut io.Writer) Interpreter)
- type Cell
- type CellError
- type Deferred
- type Displayer
- type Interpreter
- type Program
- type RLimits
- type Reply
- type Request
Constants ¶
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.
const MemoryEnv = "NOTEBOOK_MEMORY_LIMIT"
MemoryEnv is the environment variable through which the kernel gives a worker its memory limit, in bytes (Options.CellMemory).
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.
const SessionFile = "(irb)"
SessionFile is the file name a session's inputs are evaluated under, as irb's are: backtraces read (irb):3.
Variables ¶
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 ¶
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 Encode ¶
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 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
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.
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.
type Displayer ¶
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
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.
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.