gribbon
是一个简单高效的协程池三方库,通过模拟上发条的方式实现。采用单向链表维护创建的节点node
,节点数据域为核心工作协程worker
。worker
中维护状态变量,用户提交对应function
会遍历链表,判断状态决定是否使用该worker
执行对应task
。理论上,对于短作业task
,具有相当大的优势。
- 用户可自定义协程池容量。
- 以任务类型区分划分池,池子具有单一功能。
- 自动调度大量的
goroutine
,回收复用goroutine
,遵循遍历最先执行最先释放原则。 - 向外抛出异常时提供友好的访问。
- 库兼容并发安全,向用户屏蔽并发细节。
- 异步安全关闭,主要线程不受影响。
- 采用链表,无需考虑内存,极大节省内存使用量。
- 在大规模批量短作业并发任务场景下更能体现高效低耗,极大地提升了性能。
go get -u github.com/sugtex/gribbon
func hello(ctx context.Context) {
// TODO 业务逻辑
}
func helloWithArg(ctx context.Context,arg interface{}){
// TODO 断言逻辑
// TODO 业务逻辑
}
if err := gribbon.Submit(context.Background(),hello); err != nil {
// 处理err
}
if err := gribbon.SubmitWithArg(context.Background(),1,helloWithArg); err != nil {
// 处理err
}
// 是否为库内置异常
func IsGribbonErr(err error)bool{
return IsInvalidCap(err)||IsWrongSubmit(err)||IsOverMaxCap(err)||IsClosed(err)
}
// 是否无效容量
func IsInvalidCap(err error)bool{
return strings.EqualFold(err.Error(),errInvalidCap.Error())
}
// 是否错误任务提交
func IsWrongSubmit(err error)bool{
return strings.EqualFold(err.Error(),errWrongSubmit.Error())
}
// 是否到达容量限制
func IsOverMaxCap(err error) bool {
return strings.EqualFold(err.Error(), errOverMaxCap.Error())
}
// 是否处于关闭状态
func IsClosed(err error) bool {
return strings.EqualFold(err.Error(), errClosed.Error())
}
// 构建无参数池[提交含参数任务则抛出异常]
pool, err := gribbon.NewGoLink(10, false)
if err != nil {
// 处理err
return
}
if err := pool.Submit(context.Background(), hello); err != nil {
// 处理err
return
}
// 构建含参数池[提交无参数任务则抛出异常]
pool, err := gribbon.NewGoLink(10, true)
if err != nil {
// 处理err
return
}
if err := pool.SubmitWithArg(context.Background(), 1, helloWithArg); err != nil {
// 处理err
return
}
// 关闭池[异步并发安全]
if err:=pool.Close();err!=nil{
// 处理err
return
}
- 注意:死循环协程将让协程池失去意义。
gribbon
在分配完用户提交的task
后,“发条”重置,只需维护head
节点,再次分配“发条”重新启动。gribbon
面对长作业task
难以体现复用能力,worker
处于忙碌状态无法回收,不超过用户设置或库默认最大容量的情况下会开辟新的worker
进行task
调度。