Plugins are used to build parigot services that are “outside” the WASM sandbox. These services use code running inside the host to do their work. The documentation in this section is documentation about the implementation of some plugins used by built-in services. These can serve as examples of how to build your own.
import "github.com/iansmith/parigot/api/plugin"
var NoReturnedStruct = uint64(0)
func InvokeImplFromStack[T proto.Message, U proto.Message](ctx context.Context, name string, m api.Module, stack []uint64, fn func(context.Context, T, U) int32, t T, u U)
InvokeImplFromStack is the primary interface between host code and the machinery to communicate with the guest. This function takes the parameters like an api.Module and a section of the stack provided by Wazero and then reads and writes an input and output protocol buffer to the guest memory. The name is provided here just for human error messages. This functions uses pullRequestFromStack and and pushResponseToStack to do the actual work of encoding and decoding the values to/from the guest memory.
func ManufactureHostContext(ctx context.Context, funcName string) context.Context
ManufactureHostContext is a helper to return a context configured for the given function name and set the source to ServerGo.
ParigotInit is the interface that plugins must meet to be initialized. It is expected that they will use the supplied Engine in the call to Init to register Host functions.
type ParigotInit interface {
Init(ctx context.Context, e eng.Engine) bool
}
func LoadAndReturnInit(ctx context.Context, pluginPath, pluginSymbol, _ string) (ParigotInit, error)
LoadAndReturnInit is a utility function for plugins that want the default implementation. This function accepts third string param (name) but ignores it.
import "github.com/iansmith/parigot/api/plugin/file"
Buffer writecloser
type BytesBufferWrapper struct {
*bytes.Buffer
}
func NewBytesBufferWrapper(b *bytes.Buffer) *BytesBufferWrapper
func (b *BytesBufferWrapper) Close() error
type CreateHook func(path string) io.WriteCloser
type FilePlugin struct{}
func (*FilePlugin) Init(ctx context.Context, e eng.Engine) bool
enum for file status
type FileStatus int
const (
Fs_Write FileStatus = iota
Fs_Read
Fs_Close
)
func (fs FileStatus) String() string
type OpenHook func(pathOrString string) io.ReadCloser
String readcloser
type StringReaderWrapper struct {
io.Reader
}
func NewStringReaderWrapper(r io.Reader) *StringReaderWrapper
func (s *StringReaderWrapper) Close() error
import "github.com/iansmith/parigot/api/plugin/queue"
type CreateIdToKeyMappingParams struct {
IDLow sql.NullInt64
IDHigh sql.NullInt64
QueueKey sql.NullInt64
}
type CreateMessageParams struct {
IDLow sql.NullInt64
IDHigh sql.NullInt64
QueueKey sql.NullInt64
Sender []byte
Payload []byte
}
type DBTX interface {
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
PrepareContext(context.Context, string) (*sql.Stmt, error)
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}
type LocateRow struct {
IDHigh sql.NullInt64
IDLow sql.NullInt64
}
type MarkDoneParams struct {
QueueKey sql.NullInt64
IDLow sql.NullInt64
IDHigh sql.NullInt64
}
type ParigotTestMessage struct {
IDLow sql.NullInt64
IDHigh sql.NullInt64
QueueKey sql.NullInt64
LastReceived sql.NullString
ReceivedCount sql.NullInt64
OriginalSent sql.NullString
MarkedDone sql.NullString
Sender []byte
Payload []byte
}
type ParigotTestQueue struct {
ID int64
Name string
}
type ParigotTestQueueIDToKey struct {
IDLow sql.NullInt64
IDHigh sql.NullInt64
QueueKey sql.NullInt64
}
type Queries struct {
// contains filtered or unexported fields
}
func New(db DBTX) *Queries
func (q *Queries) CreateIdToKeyMapping(ctx context.Context, arg CreateIdToKeyMappingParams) (ParigotTestQueueIDToKey, error)
func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) (ParigotTestMessage, error)
func (q *Queries) CreateQueue(ctx context.Context, name string) (ParigotTestQueue, error)
func (q *Queries) DeleteQueue(ctx context.Context, id int64) error
func (q *Queries) GetQueue(ctx context.Context, id int64) (ParigotTestQueue, error)
func (q *Queries) Length(ctx context.Context, queueKey sql.NullInt64) (int64, error)
func (q *Queries) Locate(ctx context.Context, name string) (LocateRow, error)
func (q *Queries) MarkDone(ctx context.Context, arg MarkDoneParams) error
func (q *Queries) RetrieveMessage(ctx context.Context, arg RetrieveMessageParams) ([]ParigotTestMessage, error)
func (q *Queries) TestNameExists(ctx context.Context, name string) (int64, error)
func (q *Queries) UpdateMessageRetrieved(ctx context.Context, arg UpdateMessageRetrievedParams) error
func (q *Queries) WithTx(tx *sql.Tx) *Queries
type QueuePlugin struct{}
func (*QueuePlugin) Init(ctx context.Context, e eng.Engine) bool
This init functions points the host functions at the functions that are the ones to a short setup before calling the real implementation.
type RetrieveMessageParams struct {
IDHigh sql.NullInt64
IDLow sql.NullInt64
}
type UpdateMessageRetrievedParams struct {
QueueKey sql.NullInt64
IDLow sql.NullInt64
IDHigh sql.NullInt64
}
import "github.com/iansmith/parigot/api/plugin/syscall"
var ParigotInitialize apiplugin.ParigotInit = &SyscallPlugin{}
CallInfo is sent to the channels that represent service/method calls.
type CallInfo struct {
// contains filtered or unexported fields
}
CallMatcher is an internal data structure object that connects calls to Dispatch (the call) with the response which are created by ReturnValue requests.
type CallMatcher interface {
// Response is called when a return value is
// being processed. Any value that
// is returned is NOT from the execution but from
// the Response call itself. Be aware that the
// Response call is likely to be from a different
// host than the original Dispatch call.
Response(cid id.CallId, a *anypb.Any, err int32) syscall.KernelErr
// Dispatch creates the necessary entries to handle
// a future call to Response. The value returned is
// related to the Dispatch itself, it is not related
// to the execution of the call being registered.
Dispatch(hid id.HostId, cid id.CallId) syscall.KernelErr
// Ready returns a resolved call or nil if no Promises are
// resolved for the given host.
Ready(hid id.HostId) (*syscall.ResolvedCall, syscall.KernelErr)
}
HostFinder returns information about a host in the format used by the syscall struct. It is convention to use the fully qualified name of the service for the name.
type HostFinder interface {
// FindByName finds the correct host by the name field.
// If the name cannot be found, it returns nil.
FindByName(name string) *hostInfo
// FindById finds the correct host by the id field.
// If the id cannot be found it returns nil.
FindById(id id.HostId) *hostInfo
// AddHost is used to add a record to the set of hosts
// that are know. This call will panic if either the
// name or id is not set.
AddHost(name string, hid id.HostId) syscall.KernelErr
}
Service is the logical representation of a service. This is used internally and is not intended for external use.
type Service interface {
Id() id.ServiceId
// Name returns a human readable name of the service.
Name() string
// Package returns the package name (not the proto package name)
// of the service.
Package() string
// Short returns a nice-to-read version of the service's id.
Short() string
// String returns the full id of the service.
String() string
// RunRequested returns true if the service has requested
// to run, but its dependencies are not yet satisfied. Once
// they are met, the service can start and the Started()
// method will return true.
RunRequested() bool
// Started returns true if the service has started.
Started() bool
// Exported returns true if some service provider has said that
// they implement this service.
Exported() bool
// Method returns all the pairs of MethodName and MethodId
// for a service known to the SyscallData. You provide the
// service to this method to know which set of pairs you want.
Method() []*syscall.MethodBinding
// AddMethod is called by the syscall bind method to add a
// given name/id pair to this service.
AddMethod(string, id.MethodId)
//Run is badly named. This really means "block until everything
//I need is ready."
Run(context.Context) syscall.KernelErr
}
type SyscallData interface {
//ServiceByName looks up a service and returns it based on the
//values package_ and name. If this returns nil, the service could
//not be found.
ServiceByName(ctx context.Context, package_, name string) Service
//ServiceById looks up a service and returns it based on the
//value sid. If this returns nil, the service could
//not be found.
ServiceById(ctx context.Context, sid id.ServiceId) Service
//ServiceByIdString looks up a service based on the printed representation
//of the service id. If the service cannot be found ServiceByIdString
//returns nil.
ServiceByIdString(ctx context.Context, str string) Service
// SetService puts a service into SyscallData. This should only be
// called once for each package_ and name pair. It returns the
// ServiceId for the service named, creating a new one if necessary.
// The client flag should be set to true only when the requesting
// party is a client. All services should pass false here. This
// flag effectively means that the requester (package_,name) does not
// to export their service to be ready to run.
// If the bool result is false, then the pair already existed and
// we made no changes to it.
SetService(ctx context.Context, package_, name string, client bool) (Service, bool)
// Export finds a service by the given sid and then marks that
// service as being exported. This function returns nil if
// there is no such service.
Export(ctx context.Context, svc id.ServiceId) Service
// Import introduces a dendency between the sourge and dest
// services. Thus, dest must be running before source can run.
// This function returns a kernel error in two primary cases.
// 1. one of the src or destination could not be found. 2. The
// newly introduced edge would create a cycle.
Import(ctx context.Context, src, dest id.ServiceId) syscall.KernelErr
// Launch blocks the caller until all the prerequistes have been
// launched. It returns false if it returned because of
// a timeout or the service id cannot be found, otherwise true.
Launch(context.Context, id.ServiceId) syscall.KernelErr
// PathExists returns true if there is a sequence of dependency
// graph vertices that eventually leads from source to target.
PathExists(ctx context.Context, source, target string) bool
}
type SyscallPlugin struct {
}
func (*SyscallPlugin) Init(ctx context.Context, e eng.Engine) bool
Generated by gomarkdoc