Skip to content

Commit

Permalink
feat: Allow lens runtime selection via config (#2684)
Browse files Browse the repository at this point in the history
## Relevant issue(s)

Resolves #2683

## Description

Allows lens runtime selection via config/cli param.

Also adds CI jobs to the matrix to test wasmer and wazero.
  • Loading branch information
AndrewSisley authored Jun 5, 2024
1 parent 25fc07d commit dd0e5af
Show file tree
Hide file tree
Showing 28 changed files with 315 additions and 98 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/test-and-upload-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,29 @@ jobs:
client-type: [go, http, cli]
database-type: [badger-file, badger-memory]
mutation-type: [gql, collection-named, collection-save]
lens-type: [wasm-time]
detect-changes: [false]
database-encryption: [false]
include:
- os: ubuntu-latest
client-type: go
database-type: badger-memory
mutation-type: collection-save
lens-type: wasm-time
detect-changes: true
database-encryption: false
- os: ubuntu-latest
client-type: go
database-type: badger-memory
mutation-type: collection-save
lens-type: wasm-time
detect-changes: false
database-encryption: true
- os: macos-latest
client-type: go
database-type: badger-memory
mutation-type: collection-save
lens-type: wasm-time
detect-changes: false
database-encryption: false
## TODO: https://github.com/sourcenetwork/defradb/issues/2080
Expand All @@ -63,6 +67,20 @@ jobs:
## mutation-type: collection-save
## detect-changes: false
## database-encryption: false
- os: ubuntu-latest
client-type: go
database-type: badger-memory
mutation-type: collection-save
lens-type: wazero
detect-changes: false
database-encryption: false
- os: ubuntu-latest
client-type: go
database-type: badger-memory
mutation-type: collection-save
lens-type: wasmer
detect-changes: false
database-encryption: false

runs-on: ${{ matrix.os }}

Expand All @@ -80,6 +98,7 @@ jobs:
DEFRA_BADGER_FILE: ${{ matrix.database-type == 'badger-file' }}
DEFRA_BADGER_ENCRYPTION: ${{ matrix.database-encryption }}
DEFRA_MUTATION_TYPE: ${{ matrix.mutation-type }}
DEFRA_LENS_TYPE: ${{ matrix.lens-type }}

steps:
- name: Checkout code into the directory
Expand Down
2 changes: 1 addition & 1 deletion cli/server_dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func MakeServerDumpCmd() *cobra.Command {
if err != nil {
return err
}
db, err := db.NewDB(cmd.Context(), rootstore, acp.NoACP)
db, err := db.NewDB(cmd.Context(), rootstore, acp.NoACP, nil)
if err != nil {
return errors.Wrap("failed to initialize database", err)
}
Expand Down
1 change: 1 addition & 0 deletions cli/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func MakeStartCommand() *cobra.Command {
http.WithAllowedOrigins(cfg.GetStringSlice("api.allowed-origins")...),
http.WithTLSCertPath(cfg.GetString("api.pubKeyPath")),
http.WithTLSKeyPath(cfg.GetString("api.privKeyPath")),
node.WithLensRuntime(node.LensRuntimeType(cfg.GetString("lens.runtime"))),
}

if cfg.GetString("datastore.store") != configStoreMemory {
Expand Down
11 changes: 11 additions & 0 deletions client/lens.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (

"github.com/lens-vm/lens/host-go/config/model"
"github.com/sourcenetwork/immutable/enumerable"

"github.com/sourcenetwork/defradb/datastore"
)

// LensConfig represents the configuration of a Lens migration in Defra.
Expand All @@ -38,9 +40,18 @@ type LensConfig struct {
model.Lens
}

// TxnSource represents an object capable of constructing the transactions that
// implicit-transaction registries need internally.
type TxnSource interface {
NewTxn(context.Context, bool) (datastore.Txn, error)
}

// LensRegistry exposes several useful thread-safe migration related functions which may
// be used to manage migrations.
type LensRegistry interface {
// Init initializes the registry with the provided transaction source.
Init(TxnSource)

// SetMigration caches the migration for the given collection ID. It does not persist the migration in long
// term storage, for that one should call [Store.SetMigration(ctx, cfg)].
//
Expand Down
9 changes: 9 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,12 @@ Keyring backend to use. Defaults to `file`.

- `file` Stores keys in encrypted files
- `system` Stores keys in the OS managed keyring

## `lens.runtime`

The LensVM wasm runtime to run lens modules in.

Possible values:
- `wasm-time` (default): https://github.com/bytecodealliance/wasmtime-go
- `wasmer` (windows not supported): https://github.com/wasmerio/wasmer-go
- `wazero`: https://github.com/tetratelabs/wazero
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,10 @@ require (
github.com/tendermint/go-amino v0.16.0 // indirect
github.com/tendermint/tm-db v0.6.7 // indirect
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 // indirect
github.com/tetratelabs/wazero v1.5.0 // indirect
github.com/textileio/go-log/v2 v2.1.3-gke-2 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/wasmerio/wasmer-go v1.0.4 // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,8 @@ github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu
github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8 h1:RBkacARv7qY5laaXGlF4wFB/tk5rnthhPb8oIBGoagY=
github.com/teserakt-io/golang-ed25519 v0.0.0-20210104091850-3888c087a4c8/go.mod h1:9PdLyPiZIiW3UopXyRnPYyjUXSpiQNHRLu8fOsR3o8M=
github.com/tetratelabs/wazero v1.5.0 h1:Yz3fZHivfDiZFUXnWMPUoiW7s8tC1sjdBtlJn08qYa0=
github.com/tetratelabs/wazero v1.5.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
github.com/textileio/go-datastore-extensions v1.0.1 h1:qIJGqJaigQ1wD4TdwS/hf73u0HChhXvvUSJuxBEKS+c=
github.com/textileio/go-datastore-extensions v1.0.1/go.mod h1:Pzj9FDRkb55910dr/FX8M7WywvnS26gBgEDez1ZBuLE=
github.com/textileio/go-ds-badger3 v0.1.0 h1:q0kBuBmAcRUR3ClMSYlyw0224XeuzjjGinU53Qz1uXI=
Expand Down Expand Up @@ -1168,6 +1170,8 @@ github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsX
github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
github.com/wasmerio/wasmer-go v1.0.4 h1:MnqHoOGfiQ8MMq2RF6wyCeebKOe84G88h5yv+vmxJgs=
github.com/wasmerio/wasmer-go v1.0.4/go.mod h1:0gzVdSfg6pysA6QVp6iVRPTagC6Wq9pOE8J86WKb2Fk=
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4=
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM=
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
Expand Down
2 changes: 2 additions & 0 deletions http/client_lens.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type setMigrationRequest struct {
Config model.Lens
}

func (w *LensRegistry) Init(txnSource client.TxnSource) {}

func (c *LensRegistry) SetMigration(ctx context.Context, collectionID uint32, config model.Lens) error {
methodURL := c.http.baseURL.JoinPath("lens", "registry")

Expand Down
2 changes: 1 addition & 1 deletion http/handler_ccip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func TestCCIPPost_WithInvalidBody(t *testing.T) {
func setupDatabase(t *testing.T) client.DB {
ctx := context.Background()

cdb, err := db.NewDB(ctx, memory.NewDatastore(ctx), acp.NoACP, db.WithUpdateEvents())
cdb, err := db.NewDB(ctx, memory.NewDatastore(ctx), acp.NoACP, nil, db.WithUpdateEvents())
require.NoError(t, err)

_, err = cdb.AddSchema(ctx, `type User {
Expand Down
17 changes: 0 additions & 17 deletions internal/db/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
package db

import (
"github.com/lens-vm/lens/host-go/engine/module"
"github.com/sourcenetwork/immutable"

"github.com/sourcenetwork/defradb/events"
Expand Down Expand Up @@ -40,19 +39,3 @@ func WithMaxRetries(num int) Option {
db.maxTxnRetries = immutable.Some(num)
}
}

// WithLensPoolSize sets the maximum number of cached migrations instances to preserve per schema version.
//
// Will default to `5` if not set.
func WithLensPoolSize(size int) Option {
return func(db *db) {
db.lensPoolSize = immutable.Some(size)
}
}

// WithLensRuntime returns an option that sets the lens registry runtime.
func WithLensRuntime(runtime module.Runtime) Option {
return func(db *db) {
db.lensRuntime = immutable.Some(runtime)
}
}
13 changes: 0 additions & 13 deletions internal/db/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ package db
import (
"testing"

"github.com/lens-vm/lens/host-go/runtimes/wasmtime"
"github.com/stretchr/testify/assert"
)

Expand All @@ -29,15 +28,3 @@ func TestWithMaxRetries(t *testing.T) {
assert.True(t, d.maxTxnRetries.HasValue())
assert.Equal(t, 10, d.maxTxnRetries.Value())
}

func TestWithLensPoolSize(t *testing.T) {
d := &db{}
WithLensPoolSize(10)(d)
assert.Equal(t, 10, d.lensPoolSize.Value())
}

func TestWithLensRuntime(t *testing.T) {
d := &db{}
WithLensRuntime(wasmtime.New())(d)
assert.NotNil(t, d.lensRuntime.Value())
}
27 changes: 12 additions & 15 deletions internal/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (

ds "github.com/ipfs/go-datastore"
dsq "github.com/ipfs/go-datastore/query"
"github.com/lens-vm/lens/host-go/engine/module"

"github.com/sourcenetwork/corelog"
"github.com/sourcenetwork/immutable"
Expand All @@ -32,7 +31,6 @@ import (
"github.com/sourcenetwork/defradb/errors"
"github.com/sourcenetwork/defradb/events"
"github.com/sourcenetwork/defradb/internal/core"
"github.com/sourcenetwork/defradb/internal/lens"
"github.com/sourcenetwork/defradb/internal/request/graphql"
)

Expand All @@ -57,10 +55,6 @@ type db struct {

parser core.Parser

// The maximum number of cached migrations instances to preserve per schema version.
lensPoolSize immutable.Option[int]
lensRuntime immutable.Option[module.Runtime]

lensRegistry client.LensRegistry

// The maximum number of retries per transaction.
Expand All @@ -81,15 +75,17 @@ func NewDB(
ctx context.Context,
rootstore datastore.RootStore,
acp immutable.Option[acp.ACP],
lens client.LensRegistry,
options ...Option,
) (client.DB, error) {
return newDB(ctx, rootstore, acp, options...)
return newDB(ctx, rootstore, acp, lens, options...)
}

func newDB(
ctx context.Context,
rootstore datastore.RootStore,
acp immutable.Option[acp.ACP],
lens client.LensRegistry,
options ...Option,
) (*db, error) {
multistore := datastore.MultiStoreFrom(rootstore)
Expand All @@ -100,21 +96,22 @@ func newDB(
}

db := &db{
rootstore: rootstore,
multistore: multistore,
acp: acp,
parser: parser,
options: options,
rootstore: rootstore,
multistore: multistore,
acp: acp,
lensRegistry: lens,
parser: parser,
options: options,
}

// apply options
for _, opt := range options {
opt(db)
}

// lens options may be set by `WithLens` funcs, and because they are funcs on db
// we have to mutate `db` here to set the registry.
db.lensRegistry = lens.NewRegistry(db, db.lensPoolSize, db.lensRuntime)
if lens != nil {
lens.Init(db)
}

err = db.initialize(ctx)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func newMemoryDB(ctx context.Context) (*db, error) {
if err != nil {
return nil, err
}
return newDB(ctx, rootstore, acp.NoACP)
return newDB(ctx, rootstore, acp.NoACP, nil)
}

func TestNewDB(t *testing.T) {
Expand All @@ -38,7 +38,7 @@ func TestNewDB(t *testing.T) {
return
}

_, err = NewDB(ctx, rootstore, acp.NoACP)
_, err = NewDB(ctx, rootstore, acp.NoACP, nil)
if err != nil {
t.Error(err)
}
Expand Down
25 changes: 4 additions & 21 deletions internal/lens/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import (
"github.com/lens-vm/lens/host-go/config"
"github.com/lens-vm/lens/host-go/config/model"
"github.com/lens-vm/lens/host-go/engine/module"
"github.com/lens-vm/lens/host-go/runtimes/wasmtime"
"github.com/sourcenetwork/immutable"
"github.com/sourcenetwork/immutable/enumerable"

"github.com/sourcenetwork/defradb/client"
Expand Down Expand Up @@ -72,41 +70,26 @@ func newTxnCtx(txn datastore.Txn) *txnContext {
}
}

// TxnSource represents an object capable of constructing the transactions that
// implicit-transaction registries need internally.
type TxnSource interface {
NewTxn(context.Context, bool) (datastore.Txn, error)
}

// DefaultPoolSize is the default size of the lens pool for each schema version.
const DefaultPoolSize int = 5

// NewRegistry instantiates a new registery.
//
// It will be of size 5 (per schema version) if a size is not provided.
func NewRegistry(
db TxnSource,
poolSize immutable.Option[int],
runtime immutable.Option[module.Runtime],
poolSize int,
runtime module.Runtime,
) client.LensRegistry {
registry := &lensRegistry{
poolSize: DefaultPoolSize,
runtime: wasmtime.New(),
poolSize: poolSize,
runtime: runtime,
modulesByPath: map[string]module.Module{},
lensPoolsByCollectionID: map[uint32]*lensPool{},
reversedPoolsByCollectionID: map[uint32]*lensPool{},
txnCtxs: map[uint64]*txnContext{},
}

if poolSize.HasValue() {
registry.poolSize = poolSize.Value()
}
if runtime.HasValue() {
registry.runtime = runtime.Value()
}

return &implicitTxnLensRegistry{
db: db,
registry: registry,
}
}
Expand Down
11 changes: 5 additions & 6 deletions internal/lens/txn_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (

type implicitTxnLensRegistry struct {
registry *lensRegistry
db TxnSource
db client.TxnSource
}

type explicitTxnLensRegistry struct {
Expand All @@ -33,13 +33,12 @@ type explicitTxnLensRegistry struct {
var _ client.LensRegistry = (*implicitTxnLensRegistry)(nil)
var _ client.LensRegistry = (*explicitTxnLensRegistry)(nil)

func (r *implicitTxnLensRegistry) WithTxn(txn datastore.Txn) client.LensRegistry {
return &explicitTxnLensRegistry{
registry: r.registry,
txn: txn,
}
func (r *implicitTxnLensRegistry) Init(txnSource client.TxnSource) {
r.db = txnSource
}

func (r *explicitTxnLensRegistry) Init(txnSource client.TxnSource) {}

func (r *explicitTxnLensRegistry) WithTxn(txn datastore.Txn) client.LensRegistry {
return &explicitTxnLensRegistry{
registry: r.registry,
Expand Down
Loading

0 comments on commit dd0e5af

Please sign in to comment.