mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-11-25 11:29:29 +08:00
feat(plugin): Adapt to the new stateless driver API
This commit is contained in:
@@ -21,6 +21,8 @@ import (
|
|||||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
pool "github.com/jolestar/go-commons-pool/v2"
|
||||||
|
|
||||||
manager_io "github.com/OpenListTeam/wazero-wasip2/manager/io"
|
manager_io "github.com/OpenListTeam/wazero-wasip2/manager/io"
|
||||||
io_v_0_2 "github.com/OpenListTeam/wazero-wasip2/wasip2/io/v0_2"
|
io_v_0_2 "github.com/OpenListTeam/wazero-wasip2/wasip2/io/v0_2"
|
||||||
witgo "github.com/OpenListTeam/wazero-wasip2/wit-go"
|
witgo "github.com/OpenListTeam/wazero-wasip2/wit-go"
|
||||||
@@ -35,123 +37,301 @@ import (
|
|||||||
|
|
||||||
var PluginPrefix = "openlist:plugin-driver/exports@0.1.0#"
|
var PluginPrefix = "openlist:plugin-driver/exports@0.1.0#"
|
||||||
|
|
||||||
|
// DriverPlugin 是*插件*管理器 (每个 .wasm 文件一个)
|
||||||
|
// 它管理共享的 wazero 资源
|
||||||
type DriverPlugin struct {
|
type DriverPlugin struct {
|
||||||
runtime wazero.Runtime
|
plugin *PluginInfo
|
||||||
|
runtime wazero.Runtime // 共享的 wazero 运行时
|
||||||
|
compiledModule wazero.CompiledModule // 共享的已编译模块
|
||||||
|
host *DriverHost // 注册的 wasi host 资源, 这里的self.driver始终为nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WasmInstance 代表池中的一个可重用对象
|
||||||
|
// 它包含一个活动的 WASM 实例及其宿主/Guest API
|
||||||
|
type WasmInstance struct {
|
||||||
instance api.Module
|
instance api.Module
|
||||||
exports *DriverHost
|
exports *DriverHost
|
||||||
guest *witgo.Host
|
guest *witgo.Host
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 内部函数,用于动态调用 Guest 以获取属性
|
||||||
|
func (d *WasmInstance) GetProperties(ctx context.Context) (plugin_warp.DriverProps, error) {
|
||||||
|
var propertiesResult plugin_warp.DriverProps
|
||||||
|
err := d.guest.Call(ctx, PluginPrefix+"get-properties", &propertiesResult)
|
||||||
|
if err != nil {
|
||||||
|
return plugin_warp.DriverProps{}, err
|
||||||
|
}
|
||||||
|
return propertiesResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内部函数,用于动态调用 Guest 以获取表单
|
||||||
|
func (d *WasmInstance) GetFormMeta(ctx context.Context) ([]plugin_warp.FormField, error) {
|
||||||
|
var formMeta []plugin_warp.FormField
|
||||||
|
err := d.guest.Call(ctx, PluginPrefix+"get-form-meta", &formMeta)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return formMeta, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *WasmInstance) Close() error {
|
||||||
|
return i.instance.Close(context.Background())
|
||||||
|
// exports 借用WasmDriver的资源这里不销毁
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用于创建和管理 WasmInstance
|
||||||
|
type driverPoolFactory struct {
|
||||||
|
ctx context.Context
|
||||||
|
driver *WasmDriver // 指向 WasmDriver (状态持有者)
|
||||||
|
compiledModule wazero.CompiledModule // 共享的模块
|
||||||
|
runtime wazero.Runtime // 共享的运行时
|
||||||
|
host *DriverHost
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *driverPoolFactory) makeObject(ctx context.Context) (*WasmInstance, error) {
|
||||||
|
// 1. 配置模块
|
||||||
|
moduleConfig := wazero.NewModuleConfig().
|
||||||
|
WithFS(os.DirFS("/")).
|
||||||
|
WithStartFunctions("_initialize").
|
||||||
|
WithStdout(os.Stdout).
|
||||||
|
WithStderr(os.Stderr).
|
||||||
|
WithStdin(os.Stdin).
|
||||||
|
// WithSysNanosleep().
|
||||||
|
// WithSysNanotime().
|
||||||
|
// WithSysWalltime().
|
||||||
|
WithOsyield(func() {
|
||||||
|
runtime.Gosched()
|
||||||
|
}).
|
||||||
|
WithName(f.driver.plugin.plugin.ID)
|
||||||
|
|
||||||
|
instanceCtx := experimental.WithMemoryAllocator(f.ctx, experimental.MemoryAllocatorFunc(alloc.NewMemory))
|
||||||
|
|
||||||
|
// 2. 实例化共享的已编译模块
|
||||||
|
instance, err := f.runtime.InstantiateModule(instanceCtx, f.compiledModule, moduleConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to instantiate module: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 创建 Guest API
|
||||||
|
guest, err := witgo.NewHost(instance)
|
||||||
|
if err != nil {
|
||||||
|
instance.Close(ctx)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 组装 WasmInstance
|
||||||
|
wasmInstance := &WasmInstance{
|
||||||
|
instance: instance,
|
||||||
|
exports: f.host,
|
||||||
|
guest: guest,
|
||||||
|
}
|
||||||
|
return wasmInstance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeObject 创建一个新的 WasmInstance 并将其放入池中
|
||||||
|
func (f *driverPoolFactory) MakeObject(ctx context.Context) (*pool.PooledObject, error) {
|
||||||
|
wasmInstance, err := f.makeObject(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置Host端句柄,用于配置获取等host端方法
|
||||||
|
if err := wasmInstance.guest.Call(ctx, PluginPrefix+"set-handle", nil, uint32(f.driver.ID)); err != nil {
|
||||||
|
// 这里就不返回错误了,避免大量栈数据
|
||||||
|
log.Errorln(err)
|
||||||
|
wasmInstance.Close()
|
||||||
|
return nil, errors.New("Internal error in plugin")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用实例的初始化方法
|
||||||
|
ctxHandle := f.host.ContextManager().Add(ctx)
|
||||||
|
defer f.host.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
|
var result witgo.Result[witgo.Unit, plugin_warp.ErrCode]
|
||||||
|
if err := wasmInstance.guest.Call(ctx, PluginPrefix+"init", &result, ctxHandle); err != nil {
|
||||||
|
// 这里就不返回错误了,避免大量栈数据
|
||||||
|
log.Errorln(err)
|
||||||
|
wasmInstance.Close()
|
||||||
|
return nil, errors.New("Internal error in plugin")
|
||||||
|
}
|
||||||
|
if result.Err != nil {
|
||||||
|
wasmInstance.Close()
|
||||||
|
return nil, result.Err.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return pool.NewPooledObject(wasmInstance), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DestroyObject 销毁池中的 WasmInstance
|
||||||
|
func (f *driverPoolFactory) DestroyObject(ctx context.Context, object *pool.PooledObject) error {
|
||||||
|
instance := object.Object.(*WasmInstance)
|
||||||
|
log.Debugf("Destroying pooled WASM instance for plugin: %s", f.driver.Storage.MountPath)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
// 4. 调用实例的销毁化方法
|
||||||
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
var result witgo.Result[witgo.Unit, plugin_warp.ErrCode]
|
||||||
|
if err = instance.guest.Call(ctx, PluginPrefix+"drop", &result, ctxHandle); err != nil {
|
||||||
|
// 这里就不返回错误了,避免大量栈数据
|
||||||
|
log.Errorln(err)
|
||||||
|
err = errors.New("Internal error in plugin")
|
||||||
|
} else if result.Err != nil {
|
||||||
|
err = result.Err.ToError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return stderrors.Join(err, instance.Close())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateObject 验证实例是否仍然有效
|
||||||
|
func (f *driverPoolFactory) ValidateObject(ctx context.Context, object *pool.PooledObject) bool {
|
||||||
|
instance := object.Object.(*WasmInstance)
|
||||||
|
return instance.instance != nil && !instance.instance.IsClosed()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActivateObject 在借用时调用
|
||||||
|
func (f *driverPoolFactory) ActivateObject(ctx context.Context, object *pool.PooledObject) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassivateObject 在归还时调用
|
||||||
|
func (f *driverPoolFactory) PassivateObject(ctx context.Context, object *pool.PooledObject) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WasmDriver 是*驱动*实例 (每个挂载点一个)
|
||||||
|
// 它管理池和*状态*
|
||||||
|
type WasmDriver struct {
|
||||||
|
model.Storage
|
||||||
|
flag uint32
|
||||||
|
|
||||||
|
plugin *DriverPlugin
|
||||||
|
|
||||||
|
host *DriverHost
|
||||||
|
pool *pool.ObjectPool
|
||||||
|
|
||||||
|
config plugin_warp.DriverProps
|
||||||
|
additional plugin_warp.Additional
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDriverPlugin
|
||||||
|
// 创建插件管理器
|
||||||
func NewDriverPlugin(ctx context.Context, plugin *PluginInfo) (*DriverPlugin, error) {
|
func NewDriverPlugin(ctx context.Context, plugin *PluginInfo) (*DriverPlugin, error) {
|
||||||
wasmBytes, err := os.ReadFile(plugin.WasmPath)
|
wasmBytes, err := os.ReadFile(plugin.WasmPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read wasm file '%s': %w", plugin.WasmPath, err)
|
return nil, fmt.Errorf("failed to read wasm file '%s': %w", plugin.WasmPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化 Wazero 运行时,并导入 WASI
|
// 1. 创建共享的 wazero 运行时
|
||||||
rt := wazero.NewRuntime(ctx)
|
rt := wazero.NewRuntime(ctx)
|
||||||
wasi_snapshot_preview1.MustInstantiate(ctx, rt)
|
|
||||||
|
|
||||||
driverHost := NewDriverHost()
|
// 2. 注册 wasip1/wasip2 资源
|
||||||
if err := driverHost.Instantiate(ctx, rt); err != nil {
|
wasi_snapshot_preview1.MustInstantiate(ctx, rt)
|
||||||
rt.Close(ctx)
|
host := NewDriverHost()
|
||||||
log.Fatalf("编译模块失败: %v", err)
|
if err := host.Instantiate(ctx, rt); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. 编译共享的模块
|
||||||
compiledModule, err := rt.CompileModule(ctx, wasmBytes)
|
compiledModule, err := rt.CompileModule(ctx, wasmBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rt.Close(ctx)
|
rt.Close(ctx)
|
||||||
return nil, fmt.Errorf("failed to compile wasm module for plugin '%s': %w", plugin.ID, err)
|
return nil, fmt.Errorf("failed to compile wasm module for plugin '%s': %w", plugin.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为这个驱动实例创建一个独立的模块配置,特别是文件系统
|
// 4. 创建 DriverPlugin 实例(管理器)
|
||||||
moduleConfig := wazero.NewModuleConfig().
|
driverPlugin := &DriverPlugin{
|
||||||
WithFS(os.DirFS("/")). // 示例:可以根据需要配置虚拟文件系统
|
plugin: plugin,
|
||||||
WithStartFunctions("_initialize").
|
runtime: rt,
|
||||||
WithStdout(os.Stdout).
|
compiledModule: compiledModule,
|
||||||
WithStderr(os.Stderr).
|
host: host,
|
||||||
WithStdin(os.Stdin).
|
|
||||||
WithSysNanosleep().
|
|
||||||
WithSysNanotime().
|
|
||||||
WithSysWalltime().
|
|
||||||
WithOsyield(func() {
|
|
||||||
runtime.Gosched()
|
|
||||||
}).
|
|
||||||
WithName(plugin.ID)
|
|
||||||
|
|
||||||
ctx = experimental.WithMemoryAllocator(ctx, experimental.MemoryAllocatorFunc(alloc.NewMemory))
|
|
||||||
// 实例化模块,同时注入 Host API
|
|
||||||
instance, err := rt.InstantiateModule(ctx, compiledModule, moduleConfig)
|
|
||||||
if err != nil {
|
|
||||||
rt.Close(ctx)
|
|
||||||
return nil, fmt.Errorf("failed to instantiate module: %w", err)
|
|
||||||
}
|
}
|
||||||
|
return driverPlugin, nil
|
||||||
guest, err := witgo.NewHost(instance)
|
|
||||||
if err != nil {
|
|
||||||
rt.Close(ctx)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
driver := &DriverPlugin{
|
|
||||||
runtime: rt,
|
|
||||||
instance: instance,
|
|
||||||
exports: driverHost,
|
|
||||||
guest: guest,
|
|
||||||
}
|
|
||||||
return driver, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DriverPlugin) Close(ctx context.Context) error {
|
// Close 关闭共享的 wazero 运行时
|
||||||
return d.runtime.Close(ctx)
|
func (dp *DriverPlugin) Close(ctx context.Context) error {
|
||||||
|
log.Infof("Closing plugin runtime for: %s", dp.plugin.ID)
|
||||||
|
if dp.runtime != nil {
|
||||||
|
return dp.runtime.Close(ctx)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DriverPlugin) NewWasmDriver() (driver.Driver, error) {
|
// NewWasmDriver
|
||||||
var driverHandle uint32
|
// 创建*驱动实例* (每个挂载一个)
|
||||||
err := d.guest.Call(context.Background(), PluginPrefix+"[constructor]driver", &driverHandle)
|
func (dp *DriverPlugin) NewWasmDriver() (driver.Driver, error) {
|
||||||
if err != nil {
|
ctx := context.Background() // Factory/Pool context
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 1. 创建 WasmDriver 实例 (状态持有者)
|
||||||
driver := &WasmDriver{
|
driver := &WasmDriver{
|
||||||
plugin: d,
|
plugin: dp, // 指向共享资源的管理器
|
||||||
handle: driverHandle,
|
host: dp.host,
|
||||||
}
|
|
||||||
|
|
||||||
if driver.config, err = driver.GetProperties(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if driver.additional.Forms, err = driver.GetFormMeta(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type WasmDirverWarp struct {
|
type WasmDirverWarp struct {
|
||||||
*WasmDriver
|
*WasmDriver
|
||||||
}
|
}
|
||||||
driverWarp := &WasmDirverWarp{driver}
|
driverWarp := &WasmDirverWarp{driver}
|
||||||
driver.plugin.exports.driver.Set(driver.handle, driver)
|
|
||||||
runtime.SetFinalizer(driverWarp, func(driver *WasmDirverWarp) {
|
runtime.SetFinalizer(driverWarp, func(driver *WasmDirverWarp) {
|
||||||
log.Infof("runtime.SetFinalizer: %s => %d", driver.config.Name, driver.handle)
|
dp.host.driver.Remove(uint32(driver.ID))
|
||||||
driver.plugin.guest.Call(context.Background(), PluginPrefix+"[dtor]driver", driver.handle)
|
|
||||||
driver.plugin.exports.driver.Remove(driver.handle)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 3. 创建池工厂
|
||||||
|
factory := &driverPoolFactory{
|
||||||
|
ctx: ctx,
|
||||||
|
driver: driver,
|
||||||
|
compiledModule: dp.compiledModule,
|
||||||
|
runtime: dp.runtime,
|
||||||
|
host: dp.host,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 配置并创建池
|
||||||
|
poolConfig := pool.NewDefaultPoolConfig()
|
||||||
|
poolConfig.MaxIdle = 2
|
||||||
|
poolConfig.MaxTotal = 8
|
||||||
|
poolConfig.TestOnBorrow = true
|
||||||
|
poolConfig.BlockWhenExhausted = true
|
||||||
|
driver.pool = pool.NewObjectPool(ctx, factory, poolConfig)
|
||||||
|
|
||||||
|
// 5. 首次获取插件信息
|
||||||
|
initConfig := func() error {
|
||||||
|
instance, err := factory.makeObject(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer instance.Close()
|
||||||
|
|
||||||
|
props, err := instance.GetProperties(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to refresh properties: %w", err)
|
||||||
|
}
|
||||||
|
driver.config = props
|
||||||
|
|
||||||
|
forms, err := instance.GetFormMeta(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to refresh forms: %w", err)
|
||||||
|
}
|
||||||
|
driver.additional.Forms = forms
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := initConfig(); err != nil {
|
||||||
|
driver.Close(ctx) // 构造失败,关闭池
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return driverWarp, nil
|
return driverWarp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WasmDriver 实现了 Driver 接口,并代理调用到 Wasm 模块
|
// Close (在 WasmDriver 上) 关闭此*实例*的池
|
||||||
type WasmDriver struct {
|
func (d *WasmDriver) Close(ctx context.Context) error {
|
||||||
model.Storage
|
log.Infof("Closing pool for driver: %s", d.MountPath)
|
||||||
flag uint32
|
if d.pool != nil {
|
||||||
|
d.pool.Close(ctx)
|
||||||
plugin *DriverPlugin
|
}
|
||||||
handle uint32
|
return nil
|
||||||
|
|
||||||
config plugin_warp.DriverProps
|
|
||||||
additional plugin_warp.Additional
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理wasm驱动返回的错误,当错误类型为Unauthorized将驱动状态设置为nowork避免无效时继续访问
|
// handleError 处理 wasm 驱动返回的错误
|
||||||
func (d *WasmDriver) handleError(errcode *plugin_warp.ErrCode) error {
|
func (d *WasmDriver) handleError(errcode *plugin_warp.ErrCode) error {
|
||||||
if errcode != nil {
|
if errcode != nil {
|
||||||
err := errcode.ToError()
|
err := errcode.ToError()
|
||||||
@@ -168,80 +348,91 @@ func (d *WasmDriver) handleError(errcode *plugin_warp.ErrCode) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *WasmDriver) GetProperties() (plugin_warp.DriverProps, error) {
|
// // 内部函数,用于动态调用 Guest 以获取属性
|
||||||
var propertiesResult plugin_warp.DriverProps
|
// func (d *WasmDriver) getProperties(ctx context.Context) (plugin_warp.DriverProps, error) {
|
||||||
err := d.plugin.guest.Call(context.Background(), PluginPrefix+"[method]driver.get-properties", &propertiesResult, d.handle)
|
// obj, err := d.pool.BorrowObject(ctx)
|
||||||
return propertiesResult, err
|
// if err != nil {
|
||||||
}
|
// return plugin_warp.DriverProps{}, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
// }
|
||||||
|
// instance := obj.(*WasmInstance)
|
||||||
|
// defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
func (d *WasmDriver) GetFormMeta() ([]plugin_warp.FormField, error) {
|
// return instance.GetProperties(ctx)
|
||||||
var formMeta []plugin_warp.FormField
|
// }
|
||||||
err := d.plugin.guest.Call(context.Background(), PluginPrefix+"[method]driver.get-form-meta", &formMeta, d.handle)
|
|
||||||
return formMeta, err
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// // 内部函数,用于动态调用 Guest 以获取表单
|
||||||
|
// func (d *WasmDriver) getFormMeta(ctx context.Context) ([]plugin_warp.FormField, error) {
|
||||||
|
// obj, err := d.pool.BorrowObject(ctx)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
// }
|
||||||
|
// instance := obj.(*WasmInstance)
|
||||||
|
// defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
|
// return instance.GetFormMeta(ctx)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Config 返回缓存的配置
|
||||||
func (d *WasmDriver) Config() driver.Config {
|
func (d *WasmDriver) Config() driver.Config {
|
||||||
newconfig, err := d.GetProperties()
|
// props, err := d.getProperties(context.Background())
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
panic(err)
|
// log.Errorf("failed to get properties: %s", err)
|
||||||
}
|
// return d.config.ToConfig()
|
||||||
d.config = newconfig
|
// }
|
||||||
|
|
||||||
|
// d.config = props
|
||||||
return d.config.ToConfig()
|
return d.config.ToConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *WasmDriver) GetAddition() driver.Additional {
|
func (d *WasmDriver) GetAddition() driver.Additional {
|
||||||
newFormMeta, err := d.GetFormMeta()
|
// newFormMeta, err := d.getFormMeta(context.Background())
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
panic(err)
|
// log.Errorf("failed to get form meta: %s", err)
|
||||||
}
|
// return &d.additional
|
||||||
d.additional.Forms = newFormMeta
|
// }
|
||||||
|
// d.additional.Forms = newFormMeta
|
||||||
return &d.additional
|
return &d.additional
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init 初始化驱动
|
// Init 初始化驱动
|
||||||
func (d *WasmDriver) Init(ctx context.Context) error {
|
func (d *WasmDriver) Init(ctx context.Context) error {
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
log.Debugf("Re-initializing pool for plugin %s by clearing idle.", d.MountPath)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
d.pool.Clear(ctx)
|
||||||
|
|
||||||
var result witgo.Result[witgo.Unit, plugin_warp.ErrCode]
|
// 注册
|
||||||
if err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.init", &result, d.handle, ctxHandle); err != nil {
|
d.host.driver.Set(uint32(d.ID), d)
|
||||||
// 这里就不返回错误了,避免大量栈数据
|
|
||||||
log.Errorln(err)
|
|
||||||
return errors.New("Internal error in plugin")
|
|
||||||
}
|
|
||||||
if result.Err != nil {
|
|
||||||
return result.Err.ToError()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to pre-warm pool after re-init: %w", err)
|
||||||
|
}
|
||||||
|
d.pool.ReturnObject(ctx, obj)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop 销毁驱动
|
// Drop 销毁驱动 (由 Guest 调用)
|
||||||
func (d *WasmDriver) Drop(ctx context.Context) error {
|
func (d *WasmDriver) Drop(ctx context.Context) error {
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
log.Infof("Guest triggered Drop, closing pool for driver: %s", d.MountPath)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
return d.Close(ctx)
|
||||||
|
|
||||||
var result witgo.Result[witgo.Unit, plugin_warp.ErrCode]
|
|
||||||
if err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.drop", &result, d.handle, ctxHandle); err != nil {
|
|
||||||
// 这里就不返回错误了,避免大量栈数据
|
|
||||||
log.Errorln(err)
|
|
||||||
return errors.New("Internal error in plugin")
|
|
||||||
}
|
|
||||||
if result.Err != nil {
|
|
||||||
return result.Err.ToError()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *WasmDriver) GetRoot(ctx context.Context) (model.Obj, error) {
|
func (d *WasmDriver) GetRoot(ctx context.Context) (model.Obj, error) {
|
||||||
if !d.config.Capabilitys.ListFile {
|
if !d.config.Capabilitys.ListFile {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := obj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
var result witgo.Result[plugin_warp.Object, plugin_warp.ErrCode]
|
var result witgo.Result[plugin_warp.Object, plugin_warp.ErrCode]
|
||||||
err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.get-root", &result, d.handle, ctxHandle)
|
err = instance.guest.Call(ctx, PluginPrefix+"get-root", &result, ctxHandle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
@@ -264,11 +455,18 @@ func (d *WasmDriver) Get(ctx context.Context, path string) (model.Obj, error) {
|
|||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := obj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
var result witgo.Result[plugin_warp.Object, plugin_warp.ErrCode]
|
var result witgo.Result[plugin_warp.Object, plugin_warp.ErrCode]
|
||||||
err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.get-file", &result, d.handle, ctxHandle, path)
|
err = instance.guest.Call(ctx, PluginPrefix+"get-file", &result, ctxHandle, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
@@ -290,19 +488,24 @@ func (d *WasmDriver) List(ctx context.Context, dir model.Obj, args model.ListArg
|
|||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := obj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
obj := dir.(*plugin_warp.Object)
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
|
robj := dir.(*plugin_warp.Object)
|
||||||
var result witgo.Result[[]plugin_warp.Object, plugin_warp.ErrCode]
|
var result witgo.Result[[]plugin_warp.Object, plugin_warp.ErrCode]
|
||||||
|
|
||||||
param := struct {
|
param := struct {
|
||||||
Driver uint32
|
|
||||||
Handle plugin_warp.Context
|
Handle plugin_warp.Context
|
||||||
Obj *plugin_warp.Object
|
Obj *plugin_warp.Object
|
||||||
}{d.handle, ctxHandle, obj}
|
}{ctxHandle, robj}
|
||||||
err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.list-files", &result, param)
|
err = instance.guest.Call(ctx, PluginPrefix+"list-files", &result, param)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
@@ -326,22 +529,29 @@ func (d *WasmDriver) Link(ctx context.Context, file model.Obj, args model.LinkAr
|
|||||||
|
|
||||||
// 这部分资源全由Host端管理
|
// 这部分资源全由Host端管理
|
||||||
// TODO: 或许应该把创建的Stream生命周期一同绑定到此处结束,防止忘记关闭导致的资源泄漏
|
// TODO: 或许应该把创建的Stream生命周期一同绑定到此处结束,防止忘记关闭导致的资源泄漏
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
pobj, err := d.pool.BorrowObject(ctx)
|
||||||
headersHandle := d.plugin.exports.HTTPManager().Fields.Add(args.Header)
|
if err != nil {
|
||||||
defer d.plugin.exports.HTTPManager().Fields.Remove(headersHandle)
|
return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := pobj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, pobj)
|
||||||
|
|
||||||
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
headersHandle := instance.exports.HTTPManager().Fields.Add(args.Header)
|
||||||
|
defer instance.exports.HTTPManager().Fields.Remove(headersHandle)
|
||||||
|
|
||||||
obj := file.(*plugin_warp.Object)
|
obj := file.(*plugin_warp.Object)
|
||||||
|
|
||||||
var result witgo.Result[plugin_warp.LinkResult, plugin_warp.ErrCode]
|
var result witgo.Result[plugin_warp.LinkResult, plugin_warp.ErrCode]
|
||||||
|
|
||||||
param := struct {
|
param := struct {
|
||||||
Driver uint32
|
|
||||||
Handle plugin_warp.Context
|
Handle plugin_warp.Context
|
||||||
Obj *plugin_warp.Object
|
Obj *plugin_warp.Object
|
||||||
LinkArgs plugin_warp.LinkArgs
|
LinkArgs plugin_warp.LinkArgs
|
||||||
}{d.handle, ctxHandle, obj, plugin_warp.LinkArgs{IP: args.IP, Header: headersHandle}}
|
}{ctxHandle, obj, plugin_warp.LinkArgs{IP: args.IP, Header: headersHandle}}
|
||||||
err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.link-file", &result, param)
|
err = instance.guest.Call(ctx, PluginPrefix+"link-file", &result, param)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
@@ -361,7 +571,7 @@ func (d *WasmDriver) Link(ctx context.Context, file model.Obj, args model.LinkAr
|
|||||||
|
|
||||||
if result.Ok.Resource.Direct != nil {
|
if result.Ok.Resource.Direct != nil {
|
||||||
direct := result.Ok.Resource.Direct
|
direct := result.Ok.Resource.Direct
|
||||||
header, _ := d.plugin.exports.HTTPManager().Fields.Pop(direct.Header)
|
header, _ := instance.exports.HTTPManager().Fields.Pop(direct.Header)
|
||||||
link := &model.Link{URL: direct.Url, Header: http.Header(header)}
|
link := &model.Link{URL: direct.Url, Header: http.Header(header)}
|
||||||
if direct.Expiratcion.IsSome() {
|
if direct.Expiratcion.IsSome() {
|
||||||
exp := direct.Expiratcion.Some.ToDuration()
|
exp := direct.Expiratcion.Some.ToDuration()
|
||||||
@@ -371,7 +581,6 @@ func (d *WasmDriver) Link(ctx context.Context, file model.Obj, args model.LinkAr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if result.Ok.Resource.RangeStream != nil {
|
if result.Ok.Resource.RangeStream != nil {
|
||||||
streamManager := d.plugin.exports.StreamManager()
|
|
||||||
fileSize := obj.GetSize()
|
fileSize := obj.GetSize()
|
||||||
return &model.Link{
|
return &model.Link{
|
||||||
RangeReader: stream.RateLimitRangeReaderFunc(func(ctx context.Context, httpRange http_range.Range) (io.ReadCloser, error) {
|
RangeReader: stream.RateLimitRangeReaderFunc(func(ctx context.Context, httpRange http_range.Range) (io.ReadCloser, error) {
|
||||||
@@ -381,13 +590,20 @@ func (d *WasmDriver) Link(ctx context.Context, file model.Obj, args model.LinkAr
|
|||||||
} else {
|
} else {
|
||||||
size = uint64(httpRange.Length)
|
size = uint64(httpRange.Length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pobj, err := d.pool.BorrowObject(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
instance := pobj.(*WasmInstance)
|
||||||
|
|
||||||
r, w := io.Pipe()
|
r, w := io.Pipe()
|
||||||
cw := &checkWriter{W: w, N: size}
|
cw := &checkWriter{W: w, N: size}
|
||||||
streamHandle := streamManager.Add(&manager_io.Stream{
|
streamHandle := instance.exports.StreamManager().Add(&manager_io.Stream{
|
||||||
Writer: cw,
|
Writer: cw,
|
||||||
CheckWriter: cw,
|
CheckWriter: cw,
|
||||||
})
|
})
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
|
||||||
type RangeSpec struct {
|
type RangeSpec struct {
|
||||||
Offset uint64
|
Offset uint64
|
||||||
@@ -397,15 +613,17 @@ func (d *WasmDriver) Link(ctx context.Context, file model.Obj, args model.LinkAr
|
|||||||
|
|
||||||
var result witgo.Result[witgo.Unit, plugin_warp.ErrCode]
|
var result witgo.Result[witgo.Unit, plugin_warp.ErrCode]
|
||||||
param := struct {
|
param := struct {
|
||||||
Driver uint32
|
|
||||||
Handle plugin_warp.Context
|
Handle plugin_warp.Context
|
||||||
Obj *plugin_warp.Object
|
Obj *plugin_warp.Object
|
||||||
LinkArgs plugin_warp.LinkArgs
|
LinkArgs plugin_warp.LinkArgs
|
||||||
RangeSpec RangeSpec
|
RangeSpec RangeSpec
|
||||||
}{d.handle, ctxHandle, obj, plugin_warp.LinkArgs{IP: args.IP, Header: headersHandle}, RangeSpec{Offset: uint64(httpRange.Start), Size: size, Stream: streamHandle}}
|
}{ctxHandle, obj, plugin_warp.LinkArgs{IP: args.IP, Header: headersHandle}, RangeSpec{Offset: uint64(httpRange.Start), Size: size, Stream: streamHandle}}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.link-range", &result, param); err != nil {
|
defer d.pool.ReturnObject(ctx, instance)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
|
if err := instance.guest.Call(ctx, PluginPrefix+"link-range", &result, param); err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
w.CloseWithError(errs.NotImplement)
|
w.CloseWithError(errs.NotImplement)
|
||||||
return
|
return
|
||||||
@@ -423,8 +641,7 @@ func (d *WasmDriver) Link(ctx context.Context, file model.Obj, args model.LinkAr
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
return utils.NewReadCloser(r, func() error {
|
return utils.NewReadCloser(r, func() error {
|
||||||
d.plugin.exports.ContextManager().Remove(ctxHandle)
|
instance.exports.StreamManager().Remove(streamHandle)
|
||||||
streamManager.Remove(streamHandle)
|
|
||||||
return r.Close()
|
return r.Close()
|
||||||
}), nil
|
}), nil
|
||||||
}),
|
}),
|
||||||
@@ -456,21 +673,20 @@ func (d *WasmDriver) MakeDir(ctx context.Context, parentDir model.Obj, dirName s
|
|||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := obj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
obj := parentDir.(*plugin_warp.Object)
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
|
robj := parentDir.(*plugin_warp.Object)
|
||||||
var result witgo.Result[witgo.Option[plugin_warp.Object], plugin_warp.ErrCode]
|
var result witgo.Result[witgo.Option[plugin_warp.Object], plugin_warp.ErrCode]
|
||||||
|
|
||||||
params := struct {
|
if err := instance.guest.Call(ctx, PluginPrefix+"make-dir", &result, ctxHandle, robj, dirName); err != nil {
|
||||||
Driver uint32
|
|
||||||
Handle plugin_warp.Context
|
|
||||||
Obj *plugin_warp.Object
|
|
||||||
DirName string
|
|
||||||
}{d.handle, ctxHandle, obj, dirName}
|
|
||||||
|
|
||||||
if err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.make-dir", &result, params); err != nil {
|
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
@@ -491,20 +707,20 @@ func (d *WasmDriver) Rename(ctx context.Context, srcObj model.Obj, newName strin
|
|||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := obj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
obj := srcObj.(*plugin_warp.Object)
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
|
robj := srcObj.(*plugin_warp.Object)
|
||||||
var result witgo.Result[witgo.Option[plugin_warp.Object], plugin_warp.ErrCode]
|
var result witgo.Result[witgo.Option[plugin_warp.Object], plugin_warp.ErrCode]
|
||||||
|
|
||||||
params := struct {
|
err = instance.guest.Call(ctx, PluginPrefix+"rename-file", &result, ctxHandle, robj, newName)
|
||||||
Driver uint32
|
|
||||||
Handle plugin_warp.Context
|
|
||||||
Obj *plugin_warp.Object
|
|
||||||
NewName string
|
|
||||||
}{d.handle, ctxHandle, obj, newName}
|
|
||||||
err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.rename-file", &result, params)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
@@ -526,21 +742,22 @@ func (d *WasmDriver) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.
|
|||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := obj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
srcobj := srcObj.(*plugin_warp.Object)
|
srcobj := srcObj.(*plugin_warp.Object)
|
||||||
dstobj := dstDir.(*plugin_warp.Object)
|
dstobj := dstDir.(*plugin_warp.Object)
|
||||||
|
|
||||||
var result witgo.Result[witgo.Option[plugin_warp.Object], plugin_warp.ErrCode]
|
var result witgo.Result[witgo.Option[plugin_warp.Object], plugin_warp.ErrCode]
|
||||||
|
|
||||||
params := struct {
|
err = instance.guest.Call(ctx, PluginPrefix+"move-file", &result, ctxHandle, srcobj, dstobj)
|
||||||
Driver uint32
|
|
||||||
Handle plugin_warp.Context
|
|
||||||
SrcObj *plugin_warp.Object
|
|
||||||
DstObj *plugin_warp.Object
|
|
||||||
}{d.handle, ctxHandle, srcobj, dstobj}
|
|
||||||
err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.move-file", &result, params)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
@@ -562,19 +779,21 @@ func (d *WasmDriver) Remove(ctx context.Context, srcObj model.Obj) error {
|
|||||||
return errs.NotImplement
|
return errs.NotImplement
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := obj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
srcobj := srcObj.(*plugin_warp.Object)
|
srcobj := srcObj.(*plugin_warp.Object)
|
||||||
|
|
||||||
var result witgo.Result[witgo.Unit, plugin_warp.ErrCode]
|
var result witgo.Result[witgo.Unit, plugin_warp.ErrCode]
|
||||||
|
|
||||||
params := struct {
|
err = instance.guest.Call(ctx, PluginPrefix+"remove-file", &result, ctxHandle, srcobj)
|
||||||
Driver uint32
|
|
||||||
Handle plugin_warp.Context
|
|
||||||
SrcObj *plugin_warp.Object
|
|
||||||
}{d.handle, ctxHandle, srcobj}
|
|
||||||
err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.remove-file", &result, params)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return errs.NotImplement
|
return errs.NotImplement
|
||||||
@@ -596,21 +815,22 @@ func (d *WasmDriver) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.
|
|||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := obj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
srcobj := srcObj.(*plugin_warp.Object)
|
srcobj := srcObj.(*plugin_warp.Object)
|
||||||
dstobj := dstDir.(*plugin_warp.Object)
|
dstobj := dstDir.(*plugin_warp.Object)
|
||||||
|
|
||||||
var result witgo.Result[witgo.Option[plugin_warp.Object], plugin_warp.ErrCode]
|
var result witgo.Result[witgo.Option[plugin_warp.Object], plugin_warp.ErrCode]
|
||||||
|
|
||||||
params := struct {
|
err = instance.guest.Call(ctx, PluginPrefix+"copy-file", &result, ctxHandle, srcobj, dstobj)
|
||||||
Driver uint32
|
|
||||||
Handle plugin_warp.Context
|
|
||||||
SrcObj *plugin_warp.Object
|
|
||||||
DstObj *plugin_warp.Object
|
|
||||||
}{d.handle, ctxHandle, srcobj, dstobj}
|
|
||||||
err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.copy-file", &result, params)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
@@ -632,11 +852,18 @@ func (d *WasmDriver) Put(ctx context.Context, dstDir model.Obj, file model.FileS
|
|||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxHandle := d.plugin.exports.ContextManager().Add(ctx)
|
obj, err := d.pool.BorrowObject(ctx)
|
||||||
defer d.plugin.exports.ContextManager().Remove(ctxHandle)
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to borrow wasm instance: %w", err)
|
||||||
|
}
|
||||||
|
instance := obj.(*WasmInstance)
|
||||||
|
defer d.pool.ReturnObject(ctx, obj)
|
||||||
|
|
||||||
stream := d.plugin.exports.uploads.Add(&plugin_warp.UploadReadableType{FileStreamer: file, UpdateProgress: up})
|
ctxHandle := instance.exports.ContextManager().Add(ctx)
|
||||||
defer d.plugin.exports.uploads.Remove(stream)
|
defer instance.exports.ContextManager().Remove(ctxHandle)
|
||||||
|
|
||||||
|
stream := instance.exports.uploads.Add(&plugin_warp.UploadReadableType{FileStreamer: file, UpdateProgress: up})
|
||||||
|
defer instance.exports.uploads.Remove(stream)
|
||||||
|
|
||||||
dstobj := dstDir.(*plugin_warp.Object)
|
dstobj := dstDir.(*plugin_warp.Object)
|
||||||
|
|
||||||
@@ -647,17 +874,13 @@ func (d *WasmDriver) Put(ctx context.Context, dstDir model.Obj, file model.FileS
|
|||||||
exist = witgo.Some(plugin_warp.ConvertObjToObject(file.GetExist()))
|
exist = witgo.Some(plugin_warp.ConvertObjToObject(file.GetExist()))
|
||||||
}
|
}
|
||||||
|
|
||||||
params := struct {
|
uploadReq := &plugin_warp.UploadRequest{
|
||||||
Driver uint32
|
|
||||||
Handle plugin_warp.Context
|
|
||||||
DstObj *plugin_warp.Object
|
|
||||||
Upload *plugin_warp.UploadRequest
|
|
||||||
}{d.handle, ctxHandle, dstobj, &plugin_warp.UploadRequest{
|
|
||||||
Target: plugin_warp.ConvertObjToObject(file),
|
Target: plugin_warp.ConvertObjToObject(file),
|
||||||
Content: stream,
|
Content: stream,
|
||||||
Exist: exist,
|
Exist: exist,
|
||||||
}}
|
}
|
||||||
err := d.plugin.guest.Call(ctx, PluginPrefix+"[method]driver.upload-file", &result, params)
|
|
||||||
|
err = instance.guest.Call(ctx, PluginPrefix+"upload-file", &result, ctxHandle, dstobj, uploadReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, witgo.ErrNotExportFunc) {
|
if errors.Is(err, witgo.ErrNotExportFunc) {
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
|
|||||||
@@ -30,13 +30,16 @@ func (h *DriverPluginHandler) Register(ctx context.Context, plugin *PluginInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = op.RegisterDriver(func() driver.Driver {
|
err = op.RegisterDriver(func() driver.Driver {
|
||||||
driver, err := plugin.driver.NewWasmDriver()
|
tempDriver, err := plugin.driver.NewWasmDriver()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("deferred load driver plugin err: %v", err)
|
log.Errorf("deferred load driver plugin err: %v", err)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return driver
|
return tempDriver
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// 如果注册失败,关闭运行时
|
||||||
|
plugin.driver.Close(ctx)
|
||||||
return fmt.Errorf("failed to register driver in op: %w", err)
|
return fmt.Errorf("failed to register driver in op: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,21 +48,23 @@ func (h *DriverPluginHandler) Register(ctx context.Context, plugin *PluginInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *DriverPluginHandler) Unregister(ctx context.Context, plugin *PluginInfo) error {
|
func (h *DriverPluginHandler) Unregister(ctx context.Context, plugin *PluginInfo) error {
|
||||||
// 遵循用户提供的模式,传递一个工厂函数来注销
|
if plugin.driver == nil {
|
||||||
|
log.Errorf("plugin.driver is nil during unregister for plugin '%s', cannot get config", plugin.ID)
|
||||||
|
return fmt.Errorf("plugin.driver instance not found, cannot properly unregister from op")
|
||||||
|
}
|
||||||
|
|
||||||
op.UnRegisterDriver(func() driver.Driver {
|
op.UnRegisterDriver(func() driver.Driver {
|
||||||
if plugin.driver == nil {
|
tempDriver, err := plugin.driver.NewWasmDriver()
|
||||||
// 如果 driver 实例不存在,尝试临时创建一个用于获取元数据
|
if err != nil {
|
||||||
// 注意:这可能因插件的复杂性而失败
|
log.Warnf("Failed to create temp driver for unregister: %v", err)
|
||||||
tempDriver, err := NewDriverPlugin(ctx, plugin)
|
return nil
|
||||||
if err != nil {
|
|
||||||
log.Errorf("failed to create temporary driver for unregistering plugin '%s': %v", plugin.ID, err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
d, _ := tempDriver.NewWasmDriver()
|
|
||||||
return d
|
|
||||||
}
|
}
|
||||||
d, _ := plugin.driver.NewWasmDriver()
|
return tempDriver
|
||||||
return d
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if err := plugin.driver.Close(ctx); err != nil {
|
||||||
|
log.Warnf("Error closing driver plugin runtime for %s: %v", plugin.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user