host-function-library

command
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Jun 25, 2023 License: MIT Imports: 7 Imported by: 0

README

Register Host Function Library Example

This example shows how to embed functions defined in a host into plugins to expand the plugin functionalities. Host functions can be defined either in the current plugin distribution in the proto file or imported from another module defined as a source for these host functions. This allows host functions to be distributed as a library or SDK instead of having to copy them every time you create plugins.

Generate Go code for distributed host functions

A proto file is under library/json-parser/export.

// Distributing host functions without plugin code
// go:plugin type=host module=json-parser
service ParserLibrary {
  rpc ParseJson(ParseJsonRequest) returns (ParseJsonResponse) {}
}

NOTE: You must specify type=host in the comment module=json-parser and module name to be unique for the host function redistribution and registration. It represents the service is for host functions.

Then, generate source code for json-parser module hosts functions.

$ protoc --go-plugin_out=. --go-plugin_opt=paths=source_relative library/json-parser/export/library.proto 

Implement json-parser module host functions

The following interface is generated.

// Distributing host functions without plugin code
// go:plugin type=host module=json-parser
type ParserLibrary interface {
	ParseJson(context.Context, *ParseJsonRequest) (*ParseJsonResponse, error)
}

Implement that interface in separate package which will be exported to the main plugin implementation.

// ParserLibraryImpl implements export.ParserLibrary functions
type ParserLibraryImpl struct{}

// ParseJson is embedded into the plugin and can be called by the plugin.
func (ParserLibraryImpl) ParseJson(_ context.Context, request *export.ParseJsonRequest) (*export.ParseJsonResponse, error) {
    var person export.Person
    if err := json.Unmarshal(request.GetContent(), &person); err != nil {
        return nil, err
    }

    return &export.ParseJsonResponse{Response: &person}, nil
}

Then, generate source code stubs for the base plugin.

$ protoc --go-plugin_out=. --go-plugin_opt=paths=source_relative proto/greer.proto 

Register exported hosts functions module int while providing new WazeroRuntime in the proto.NewGreeterPlugin().

ctx := context.Background()
p, err := proto.NewGreeterPlugin(ctx, proto.WazeroRuntime(func(ctx context.Context) (wazero.Runtime, error) {
    r, err := proto.DefaultWazeroRuntime()(ctx)
    if err != nil {
        return nil, err
    }
    return r, export.Instantiate(ctx, r, impl.ParserLibraryImpl{})
}))

Call host functions in a plugin

The exported as a library or SDK host functions can be called in plugins.

parserLibrary := export.NewParserLibrary()

// Call the host function to parse JSON
resp, err := parserLibrary.ParseJson(ctx, &export.ParseJsonRequest{
    Content: []byte(fmt.Sprintf(`{"name": "%s", "age": 20}`, sanrequest.Message)),
})
if err != nil {
    return nil, err
}

Compile a plugin

Use TinyGo to compile the plugin to Wasm.

$ go generate main.go

Run

main.go loads the above plugin.

$ go run main.go
2022/08/28 10:13:57 Sending a HTTP request...
Hello, Sato. This is Yamada-san (age 20).

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
library

Jump to

Keyboard shortcuts

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