eventbus(事件总线)-学习笔记

本文介绍了一种事件总线的设计方案,包括订阅者、发布者及控制器接口定义,详细解释了同步与异步订阅、发布的过程,并展示了如何通过WaitGroup机制确保异步回调的完成。

【学习资源超链接】<—点这

event_bus

定义BusSubscriber接口,声明订阅相关函数。

type BusSubscriber interface {
	Subscribe(topic string, fn interface{}) error
	SubscribeAsync(topic string, fn interface{}, transactional bool) error
	SubscribeOnce(topic string, fn interface{}) error
	SubscribeOnceAsync(topic string, fn interface{}) error
	Unsubscribe(topic string, handler interface{}) error
}

定义BusPublisher接口,声明发布相关函数。

type BusPublisher interface {
	Publish(topic string, args ...interface{})
}

定义BusController接口,声明控制总线相关函数。WaitAsync等待所有异步回调完成

type BusController interface {
	HasCallback(topic string) bool
	WaitAsync()
}

定义Bus接口,作为实现总线对外的总接口,包含三个功能:订阅、发布、控制。

type Bus interface {
	BusController
	BusSubscriber
	BusPublisher
}

订阅

doSubscribe是文件私有函数,处理订阅逻辑,并支持公共订阅函数使用。将函数、绑定名topic和事件句柄eventHandler传入。如果传入fn的不是函数会返回错误。

func (bus *EventBus) doSubscribe(topic string, fn interface{}, handler *eventHandler) error

公共订阅函数中:

  • Subscribe 同步订阅主题。执行后将删除处理程序。如果’fn’不是函数,则返回错误。async=false
  • SubscribeAsync通过异步回调订阅主题。Transactional变量确定主题的后续回调是串行运行(true)还是并行运行(false)。如果“fn”不是函数,则返回错误。async=true
    transactional=true时,会将handler上锁执行doPublish,保证顺序。
    transactional=false时,完全由go程异步。
  • SubscribeOnce 订阅一次主题。执行后将删除处理程序。如果’fn’不是函数,则返回错误。async=false,flag=true
  • SubscribeOnceAsync订阅一次主题,异步回调处理程序将在执行后删除。如果’fn’不是函数,则返回错误。async=true,flag=true

发布

私有发布函数支持多个函数的发布,发布内容存在则更新,不存在利用反射新增元素,然后激活回调函数。提供给公共发布函数调用。

//同步
func (bus *EventBus) doPublish(handler *eventHandler, topic string, args ...interface{}) 
//异步 内部加解锁注意理解
func (bus *EventBus) doPublishAsync(handler *eventHandler, topic string, args ...interface{})

公共发布函数,根据handler的async字段判断是否同步回调。

func (bus *EventBus) Publish(topic string, args ...interface{})

sync.WaitGroup机制

sync.WaitGroup是被设计用来实现同步问题的一个函数,它维护一个计数器,初始为0。它有三个方法来对计数器进行操作或判断:Add() Done() Wait()。

  1. Add(n) 把计数器设置为n
  2. Done() 每次把计数器-1
  3. wait() 会阻塞代码的运行,直到计数器的值减为0。
补充
  1. map遍历

关于遍历需要指定元素值,如果用&stu赋值会导致全是第一个元素,后续数据丢失。

for i, stu := range stus {
	m[stu.Name] = &stus[i]
}
  1. 数组定义:
// 指定大小,同时可以通过下标来指定内容
var strs [3]string = [3]string{1 : "a"}
// 简短写法
arrays := [5]int64{4: 1}
// 使用...自导推到长度
b := [...]string{"Penn", "Teller"}
  1. 切片空间释放
    从大切片里面截取小切片,会导致大切片被占用无法释放从而浪费空间。
    解决方法:寻找到小块感兴趣的内容之后,使用make函数重新分配一个新的切片,将感兴趣内容使用copy函数复制到新的切片上,并且将该新的切片作为函数值返回

  2. 单元测试

类型格式作用
单元测试前缀Test测试程序的一些逻辑
基准(压力)测试前缀Benchmark测试函数的性能
示例测试前缀Example为文档提供示例文档
模糊(随机)测试前缀Fuzz生成一个随机测试用例去覆盖人为测不到的各种复杂场景
  • 测试网络库net/http/httptest
  • 一个包一个文件夹,针对于包设置test文件
  1. Golang技术栈学习
  2. euler案例:价格变动->保存新价格和事件->向事件总线发送消息->日志模块修改状态
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值