timecraft

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2023 License: AGPL-3.0 Imports: 42 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ConfigPath human.Path = defaultConfigPath

ConfigPath is the path to the timecraft configuration.

Functions

func CreateRegistry

func CreateRegistry(config *Config) (*timemachine.Registry, error)

CreateRegistry creates a timemachine registry.

func NewRuntime

func NewRuntime(ctx context.Context, config *Config) (wazero.Runtime, error)

NewRuntime constructs a wazero.Runtime that's configured according to the provided timecraft Config.

func OpenConfig

func OpenConfig() (io.ReadCloser, string, error)

OpenConfig opens the configuration file.

func OpenRegistry

func OpenRegistry(config *Config) (*timemachine.Registry, error)

OpenRegistry opens a timemachine registry.

func Version

func Version() string

Version returns the timecraft version.

Types

type Config

type Config struct {
	Registry struct {
		Location Option[human.Path] `json:"location"`
	} `json:"registry"`
	Cache struct {
		Location Option[human.Path] `json:"location"`
	} `json:"cache"`
}

Config is timecraft configuration.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig is the default configuration.

func LoadConfig

func LoadConfig() (*Config, error)

LoadConfig opens and reads the configuration file.

func ReadConfig

func ReadConfig(r io.Reader) (*Config, error)

ReadConfig reads and parses configuration.

type ExitError

type ExitError uint32

ExitError indicates a WebAssembly module exited with a non-zero exit code.

func (ExitError) Error

func (e ExitError) Error() string

type HTTPRequest

type HTTPRequest struct {
	Method  string
	Path    string // TODO: other parts of the URL, e.g. query
	Headers http.Header
	Body    []byte
	Port    int
}

HTTPRequest is an HTTP request.

It's intended to buffer a full request in memory in case it needs to be used multiple times, compared to a http.Request with a generic io.ReadCloser Body that can only be consumed once.

type HTTPResponse

type HTTPResponse struct {
	StatusCode int
	Headers    http.Header
	Body       []byte
}

HTTPResponse is an HTTP response.

type LogSpec

type LogSpec struct {
	ProcessID   ProcessID
	StartTime   time.Time
	Compression timemachine.Compression
	BatchSize   int
}

LogSpec is details about the log that records a trace of execution.

func (*LogSpec) Fork

func (l *LogSpec) Fork() *LogSpec

type ModuleSpec

type ModuleSpec struct {
	// Path is the path of the WebAssembly module.
	Path string

	// Name of the exported function to call in the WebAssembly module.
	// If empty, the _start function will be executed.
	Function string

	// Args are command-line arguments to pass to the module.
	Args []string

	// Env is the environment variables to pass to the module.
	Env []string

	// Dirs is a set of directories to make available to the module.
	Dirs []string

	// Listens is a set of listener sockets to make available to the module.
	Listens []string

	// Dials is a set of connection sockets to make available to the module.
	Dials []string

	// Sockets is the name of a sockets extension to use, or "auto" to
	// automatically detect the sockets extension.
	Sockets string

	// Stdio file descriptors.
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer

	// Trace is an optional writer that receives a trace of system calls
	// made by the module.
	Trace io.Writer

	// Allow the module to bind to the host network when opening listening
	// sockets.
	HostNetworkBinding bool

	// OutboundProxy is a run specification for a WebAssembly module to be
	// spawn alongside this module. The extra module is a sidecar that proxies
	// outbound network traffic.
	OutboundProxy *ModuleSpec
}

ModuleSpec is the details about what WebAssembly module to execute, how it should be initialized, and what its inputs are.

func (*ModuleSpec) Key

func (m *ModuleSpec) Key() string

Key is a string that uniquely identifies the ModuleSpec.

type Option

type Option[T any] struct {
	// contains filtered or unexported fields
}

Option is a value of type T or null.

func Some

func Some[T any](v T) Option[T]

Some creates an Option with a value.

func (Option[T]) MarshalJSON

func (v Option[T]) MarshalJSON() ([]byte, error)

func (Option[T]) MarshalYAML

func (v Option[T]) MarshalYAML() (any, error)

func (*Option[T]) UnmarshalJSON

func (v *Option[T]) UnmarshalJSON(b []byte) error

func (*Option[T]) UnmarshalYAML

func (v *Option[T]) UnmarshalYAML(node *yaml.Node) error

func (Option[T]) Value

func (v Option[T]) Value() (T, bool)

Value retrieves the value and a null flag from the Option.

type ProcessID

type ProcessID = uuid.UUID

ProcessID is a process identifier.

type ProcessInfo

type ProcessInfo struct {
	// ID is the ID of the process.
	ID ProcessID

	// Addr is a unique IP address for the process.
	Addr netip.Addr

	// DialContext is a dialer that can be used to send work to the
	// process over the work socket.
	DialContext func(ctx context.Context, network, address string) (net.Conn, error)

	// ParentID is the ID of the process that spawned this one (if applicable).
	ParentID *ProcessID
	// contains filtered or unexported fields
}

ProcessInfo is information about a process.

type ProcessManager

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

ProcessManager runs WebAssembly modules.

A running WebAssembly module is known as a process. Processes are allowed to spawn other processes. The ProcessManager manages the lifecycle of processes.

func NewProcessManager

func NewProcessManager(ctx context.Context, registry *timemachine.Registry, runtime wazero.Runtime, serverFactory *ServerFactory, adapter func(ProcessID, wasi.System) wasi.System) *ProcessManager

NewProcessManager creates an ProcessManager.

func (*ProcessManager) Close

func (pm *ProcessManager) Close() error

Close closes the process manager.

func (*ProcessManager) Lookup

func (pm *ProcessManager) Lookup(processID ProcessID) (process ProcessInfo, ok bool)

Lookup looks up a process by ID.

The return flag is true if the process exists and is alive, and false otherwise.

func (*ProcessManager) Start

func (pm *ProcessManager) Start(moduleSpec ModuleSpec, logSpec *LogSpec, parentID *ProcessID) (ProcessID, error)

Start starts a process.

The ModuleSpec describes the module to be executed. An optional LogSpec can be provided to instruct the ProcessManager to record a trace of execution to a log.

If Start returns an error it indicates that there was a problem initializing the WebAssembly module. If the WebAssembly module starts successfully, any errors that occur during execution must be retrieved via Wait or WaitAll.

func (*ProcessManager) Wait

func (pm *ProcessManager) Wait(processID ProcessID) error

Wait blocks until a process exits.

func (*ProcessManager) WaitAll

func (pm *ProcessManager) WaitAll() error

WaitAll blocks until all processes have exited.

type Replay

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

Replay coordinates the replay of WebAssembly modules.

func NewReplay

func NewReplay(registry *timemachine.Registry, runtime wazero.Runtime, processID uuid.UUID) *Replay

NewReplay creates a Replay for a WebAssembly modules with a recorded trace of execution, identified by processID.

func (*Replay) ModuleCode

func (r *Replay) ModuleCode(ctx context.Context) ([]byte, string, error)

ModuleCode reads the module's WebAssembly code.

func (*Replay) RecordReader

func (r *Replay) RecordReader(ctx context.Context) (records stream.ReadCloser[timemachine.Record], startTime time.Time, err error)

RecordReader constructs a reader for the process replay log.

func (*Replay) Replay

func (r *Replay) Replay(ctx context.Context) error

Replay replays process execution.

func (*Replay) ReplayRecords

func (r *Replay) ReplayRecords(ctx context.Context, function string, moduleCode []byte, records stream.Reader[timemachine.Record]) error

ReplayRecords replays process execution using the specified records.

func (*Replay) ReplayRecordsModule

func (r *Replay) ReplayRecordsModule(ctx context.Context, function string, compiledModule wazero.CompiledModule, records stream.Reader[timemachine.Record]) error

ReplayRecordsModule replays process execution using the specified records on a pre-compiled module.

func (*Replay) SetStderr

func (r *Replay) SetStderr(w io.Writer)

SetStderr sets the io.Writer that receives stderr from the replay.

func (*Replay) SetStdout

func (r *Replay) SetStdout(w io.Writer)

SetStdout sets the io.Writer that receives stdout from the replay.

func (*Replay) SetTrace

func (r *Replay) SetTrace(w io.Writer)

SetTrace sets the io.Writer that receives a trace of system calls from the replay.

type Server

type Server struct {
	serverv1connect.UnimplementedTimecraftServiceHandler
	// contains filtered or unexported fields
}

Server is a gRPC server that's available to guests. Every WebAssembly module has its own instance of a gRPC server.

func (*Server) Close

func (s *Server) Close() error

func (*Server) DiscardTasks

func (s *Server) DiscardTasks(ctx context.Context, req *connect.Request[v1.DiscardTasksRequest]) (*connect.Response[v1.DiscardTasksResponse], error)

func (*Server) Kill

func (s *Server) Kill(ctx context.Context, req *connect.Request[v1.KillRequest]) (*connect.Response[v1.KillResponse], error)

func (*Server) LookupTasks

func (s *Server) LookupTasks(ctx context.Context, req *connect.Request[v1.LookupTasksRequest]) (*connect.Response[v1.LookupTasksResponse], error)

func (*Server) PollTasks

func (s *Server) PollTasks(ctx context.Context, req *connect.Request[v1.PollTasksRequest]) (*connect.Response[v1.PollTasksResponse], error)

func (*Server) ProcessID

func (s *Server) ProcessID(context.Context, *connect.Request[v1.ProcessIDRequest]) (*connect.Response[v1.ProcessIDResponse], error)

func (*Server) Serve

func (s *Server) Serve(l net.Listener) error

Serve serves using the specified net.Listener.

func (*Server) Spawn

func (s *Server) Spawn(ctx context.Context, req *connect.Request[v1.SpawnRequest]) (*connect.Response[v1.SpawnResponse], error)

func (*Server) SubmitTasks

func (s *Server) SubmitTasks(ctx context.Context, req *connect.Request[v1.SubmitTasksRequest]) (*connect.Response[v1.SubmitTasksResponse], error)

func (*Server) Version

func (s *Server) Version(context.Context, *connect.Request[v1.VersionRequest]) (*connect.Response[v1.VersionResponse], error)

type ServerFactory

type ServerFactory struct {
	ProcessManager *ProcessManager
	Scheduler      *TaskScheduler
}

ServerFactory is used to create Server instances.

func (*ServerFactory) NewServer

func (f *ServerFactory) NewServer(ctx context.Context, processID uuid.UUID, moduleSpec ModuleSpec, logSpec *LogSpec) *Server

NewServer creates a new Server.

type TaskGroup

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

TaskGroup manages a logical group of tasks.

It exposes nearly the same API as the TaskScheduler, but adds a new Poll method, ensures that only tasks local to the group can be retrieved or discarded through the same group, and automatically discards all in-flight tasks when closed.

func NewTaskGroup

func NewTaskGroup(s *TaskScheduler) *TaskGroup

NewTaskGroup creates a new task group.

func (*TaskGroup) Close

func (g *TaskGroup) Close() error

Close closes the TaskGroup and discards all in-flight tasks.

func (*TaskGroup) Discard

func (g *TaskGroup) Discard(id TaskID) (ok bool)

Discard discards a task by ID.

See TaskScheduler.Discard for more information.

func (*TaskGroup) Lookup

func (g *TaskGroup) Lookup(id TaskID) (task TaskInfo, ok bool)

Lookup looks up a task by ID.

See TaskScheduler.Lookup for more information.

func (*TaskGroup) Poll

func (g *TaskGroup) Poll() <-chan TaskID

Poll returns a channel that receives completion notifications for tasks in the group.

func (*TaskGroup) Submit

func (g *TaskGroup) Submit(moduleSpec ModuleSpec, logSpec *LogSpec, input TaskInput, processID ProcessID) (TaskID, error)

Submit submits a task for execution.

See TaskScheduler.Submit for more information.

type TaskID

type TaskID = uuid.UUID

TaskID is a task identifier.

type TaskInfo

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

TaskInfo is information about a task.

type TaskInput

type TaskInput interface {
	// contains filtered or unexported methods
}

TaskInput is input for a task.

type TaskOutput

type TaskOutput interface {
	// contains filtered or unexported methods
}

TaskOutput is output from a task.

type TaskScheduler

type TaskScheduler struct {
	ProcessManager *ProcessManager
	// contains filtered or unexported fields
}

TaskScheduler schedules tasks across processes.

A task is a unit of work. A process (managed by the ProcessManager) is responsible for executing one or more tasks. The management of processes to execute tasks and the scheduling of tasks across processes are both implementation details of the scheduler.

func (*TaskScheduler) Close

func (s *TaskScheduler) Close() error

Close closes the TaskGroup and discards all in-flight tasks.

func (*TaskScheduler) Discard

func (s *TaskScheduler) Discard(id TaskID) (ok bool)

Discard discards a task by ID.

func (*TaskScheduler) Lookup

func (s *TaskScheduler) Lookup(id TaskID) (task TaskInfo, ok bool)

Lookup looks up a task by ID.

func (*TaskScheduler) Submit

func (s *TaskScheduler) Submit(moduleSpec ModuleSpec, logSpec *LogSpec, input TaskInput, processID ProcessID, completions chan<- TaskID) (TaskID, error)

Submit submits a task for execution.

The method returns a TaskID that can be passed to Lookup to query the task status and fetch task output.

The method accepts an optional channel that receives a completion notification once the task is complete (succeeds, or fails permanently).

Once a task is complete, it must be discarded via Discard.

type TaskState

type TaskState int

TaskState is the state of a task.

const (
	// Queued indicates that the task is waiting to be scheduled.
	Queued TaskState = iota + 1

	// Initializing indicates that the task is in the process of being scheduled
	// on to a process.
	Initializing

	// Executing indicates that the task is currently being executed.
	Executing

	// Error indicates that the task failed with an error. This is a terminal
	// status.
	Error

	// Success indicates that the task executed successfully. This is a terminal
	// status.
	Success
)

Jump to

Keyboard shortcuts

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