跳到主要内容
版本:0.4.x(Latest)

基本介绍

钩子声明覆盖插件对主框架扩展点事件的订阅。源码插件通过pluginhost.Declarations.Hooks()注册事件处理器,在特定事件发生时执行回调逻辑。动态插件通过backend/hooks/*.yaml声明HookSpec,构建工具会将其嵌入.wasm产物的lina.plugin.backend.hooks自定义段。

能力阶段:声明期

类型支持:源码插件、动态插件

能力设计

扩展点分类

扩展点分为钩子扩展点(Hook)和注册扩展点(Registrar)两类。钩子扩展点用于事件通知,注册扩展点用于声明收集。

钩子扩展点列表

扩展点说明
auth.login.succeeded用户登录成功
auth.login.failed用户登录失败
auth.logout.succeeded用户登出成功
plugin.installed插件安装完成
plugin.enabled插件启用
plugin.disabled插件禁用
plugin.uninstalled插件卸载完成
plugin.upgraded插件升级完成
system.started系统启动完成

上表是pluginhost运行时发布的钩子扩展点。当前linactl动态插件构建器扫描backend/hooks/*.yaml时,只发布auth.login.succeededauth.login.failedauth.logout.succeededplugin.installedplugin.enabledplugin.disabledplugin.uninstalledsystem.started;动态插件不要在backend/hooks/*.yaml中声明plugin.upgraded

执行模式

模式说明适用扩展点
blocking阻塞执行,回调完成后才继续后续流程所有扩展点
async异步执行,回调在独立协程中执行钩子扩展点

钩子扩展点支持blockingasync两种模式;注册扩展点只支持blocking模式。

钩子负载

钩子处理器接收HookPayload参数,包含事件数据:

方法说明
ExtensionPoint()返回当前扩展点
Value(key)按键读取负载值
Values()返回所有负载键值对
Services()返回Services,用于访问宿主能力

负载键

说明
pluginId插件标识
name名称
version版本
status状态
userName用户名
ip客户端IP
clientType客户端类型
browser浏览器
os操作系统
message消息
reason原因

认证事件原因码

原因码说明
loginSuccessful登录成功
loginFailed登录失败
logoutSuccessful登出成功
invalidCredentials无效凭证
userDisabled用户已禁用
ipBlacklistedIP已列入黑名单

动态插件钩子声明(HookSpec)

动态插件通过backend/hooks/*.yaml文件声明HookSpec钩子契约:

字段类型说明
eventstring扩展点名称;使用linactl构建时以动态构建器发布的钩子列表为准
actionstring动作类型:insertsleeperror
modestring执行模式:blockingasync
tablestring关联表名
fieldsmap字段映射
timeoutMsint超时毫秒数
sleepMsint休眠毫秒数(sleep动作)
errorMessagestring错误消息(error动作)

接口定义

源码插件接口

源码插件通过Hooks()注册事件处理器:

方法说明
RegisterHook注册事件处理器,指定扩展点、执行模式和处理函数

动态插件接口

动态插件通过backend/hooks/*.yaml声明钩子契约,构建后嵌入.wasm产物的lina.plugin.backend.hooks自定义段。

能力使用

源码插件使用

源码插件在init()中通过pluginhost.NewDeclarations返回的钩子声明入口注册事件处理器:

func init() {
plugin := pluginhost.NewDeclarations("my-author-my-domain-my-cap")
if err := plugin.Hooks().RegisterHook(
pluginhost.ExtensionPointAuthLoginSucceeded,
pluginhost.CallbackExecutionModeAsync,
func(ctx context.Context, payload pluginhost.HookPayload) error {
userName := payload.Value("userName")
ip := payload.Value("ip")
// 记录登录日志
return logLoginEvent(ctx, userName.(string), ip.(string))
},
); err != nil {
panic(err)
}

if err := pluginhost.RegisterSourcePlugin(plugin); err != nil {
panic(err)
}
}

注册系统启动钩子:

err := plugin.Hooks().RegisterHook(
pluginhost.ExtensionPointSystemStarted,
pluginhost.CallbackExecutionModeBlocking,
func(ctx context.Context, payload pluginhost.HookPayload) error {
// 系统启动后执行初始化
return initializePlugin(ctx)
},
)

动态插件使用

动态插件在backend/hooks/001-plugin-enabled.yaml中声明钩子契约:

hooks:
- event: plugin.enabled
action: insert
mode: blocking
table: plugin_events
fields:
plugin_id: "{{pluginId}}"
event: "enabled"
timestamp: "{{now}}"

构建工具会扫描backend/hooks/*.yaml,校验HookSpec后嵌入.wasm产物的lina.plugin.backend.hooks自定义段。

设计约束

  • 扩展点必须在宿主注册表中。 注册未定义的扩展点会返回错误。
  • 执行模式必须匹配扩展点类型。 注册扩展点只支持blocking模式。
  • 阻塞回调影响主流程。 blocking模式的回调会阻塞后续流程,应快速返回。
  • 异步回调独立执行。 async模式的回调在独立协程中执行,失败不影响主流程。
  • 负载值需要类型断言。 HookPayload.Value()返回interface{},调用方需要类型断言。
  • 动态插件钩子通过契约声明。 动态插件的钩子在构建期通过backend/hooks/*.yaml声明,不支持运行时动态注册。

相关文档