Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Plugin #67

Merged
merged 31 commits into from Sep 27, 2020
Merged

WIP: Plugin #67

merged 31 commits into from Sep 27, 2020

Conversation

FINCTIVE
Copy link
Contributor

@FINCTIVE FINCTIVE commented Sep 8, 2020

Add plugin support for go-wechaty

Discussion: wechaty/summer#9
“开源软件供应链点亮计划-暑期2020” 为 go-wechaty 设计实现插件体系项目。

@FINCTIVE
Copy link
Contributor Author

go-wechaty 插件机制

实现思路

增加 wechaty.Plugin 结构用于存储插件相应的回调函数,它支持 Wechaty 中的所有事件注册函数(比如 OnMessage()),使用方式与 Wechaty 实例一致,便于把 Bot 代码封装成为插件。

新增加 wechaty.Context 结构类型用于一轮消息事件的控制、传递。在每一次接收到新的消息事件时传入一个新的变量。同时,该结构实现了 context.Context 接口。

功能

调用顺序(优先级)

按照注册顺序依次调用。

其中,Bot 逻辑代码与插件逻辑代码可以存在交错执行顺序。即:

var bot = wechaty.NewWechaty()
bot.OnMessage(func(context *wechaty.Context, message *user.Message) {
	// Part A
})
bot.Use(pluginB).Use(pluginC)
bot.OnMessage(func(context *wechaty.Context, message *user.Message) {
	// Part D
}

执行顺序:Part A → pluginB → pluginC → Part D

开关

  • 禁用、启用插件。

    对应方法:Plugin.SetEnable()

    通过加锁的方式修改插件属性变量。这个方法是并发安全的。

  • 在本轮消息事件中,暂时禁用某一个插件。

    对应方法:Context.DisableOnce()

  • 消息拦截,跳过后续插件对该本轮消息事件的处理。同时终止所有仍在进行的插件代码操作,即先前插件产生的 Goroutine。

    对应方法:Context.Abort() 以及 Context.Done()

  • 在并发程序中,控制插件内部 goroutine 的结束。用法与 Go 语言中的 context.Context (WithCancel())相同。

    对应方法:Context.Abort() 以及 Context.Done()

    示例:

    plugin := NewPlugin()
    plugin.OnMessage(func(context *wechaty.Context, message *user.Message) {
    	go func(ctx context.Context) {
            // other code ...
            select {
            case <-ctx.Done():
                // terminated by wechaty.Context.Abort()
    
            // other code ...
    
            }
    	}(context)
    })
    
    // other code ...
    
    // context.Abort() will terminate the goroutine

数据传递

通过 Context 传递数据,数据只在本轮消息时间有效。

不支持并发读写。

对应方法:Context.SetData(), Context.GetData()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants