一文教你如何封装安全的go
前言
在业务代码开发过程中,我们会有很大概率使用go语言的goroutine来开启一个新的goroutine执行另外一段业务,或者开启多个goroutine来并行执行多个业务逻辑。所以我为hade框架增加了两个方法goroutine.safego 和 goroutine.safegoandwait。
封装
safego
safego 这个函数,提供了一种goroutine安全的函数调用方式。主要适用于业务中需要进行开启异步goroutine业务逻辑调用的场景。
调用方式参照如下的单元测试用例:
safegoandwait
safegoandwait 这个函数,提供安全的多并发调用方式。该函数等待所有函数都结束后才返回。
调用方式参照如下的单元测试用例:
实现说明
实现方面,有几个难点记录下。
首先是接口设计方面
可以看到handler函数在两个接口中是不一样的。在safego接口中,handler定义为func()
而在safegoandwait中,定义为func() error
两者的区别就在于safego这个接口是没有能力处理error的,因为它go出去一个goroutine就直接进行接下来的操作了。而safegoandwait是必须等到所有的请求结束,所以它是有能力接收到error的。
所以safego的handler没有必要设置error返回值,而safegoandwait是可以设置error的。
其次是日志兼容hade
如果出现了panic,如何将panic的日志打印出来。
整个框架我们并不希望有任何的全局变量,包括全局的log,所以我这里做了一个兼容逻辑。
如果只是传递一个context,我们就使用官方的log包进行打印。
如果传递的是一个即实现了context,又实现了container接口的结构,我们就从container中获取日志服务,来进行日志打印。这样框架的所有日志就能统一在日志打印里面。
由于我们修改了gin的context,让它支持了我们的container容器结构,所以我们可以直接将gin.context传递进来。具体使用起来就像这样了:
最后是打印panic的trace记录
官方的panic其实打印的是所有goroutine的堆栈信息。但是这里我们希望打印的是出panic的那个堆栈信息。所以我们会使用
来打印出问题的goroutine的堆栈信息。
为了打印美观,这里将换行符统一替换为\n 来进行展示。
具体的实现代码可以参考github地址:https://github.com/gohade/hade/blob/main/framework/util/goroutine/goroutine.go
说明文档:https://github.com/gohade/hade/blob/main/docs/guide/util.md
总结
为hade封装了两个safego方法。特别是第二个safegoandwait,在实际工作中确实是非常有用的。
到此这篇关于如何封装安全的go的文章就介绍到这了,更多相关封装安全的go内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!