golang 开启协程

golang 协程处理

协程在golang中相对比较廉价。在特别在做对比的时候特别有优势。在服务重构切换的时候往往需要实现对比机制。新服务调用旧服务做对比上报。
如果仅仅是用来上报数据。那么就可以异步化,不影响当前的流程。这时候开启协程无疑是最好的办法。

版本一

go compareFee(ctx)

在得到当前运费的结果之后,开启协程。让他在新的协程调用旧服务,获取了之后对比完,上报cat 或者其他服务。这个时候整体功能得以实现。但是协程有个问题就是如果出现panic, 会到导致整体服务的panic。

版本二

func safeCompareFee(ctx context.Context, goApiResult *EsfResult, data *schema.ApiNewCalculateEsfRequest, calculateData *sfdata.CalculateData, requestID string) {
	// protect process
	defer func() {

		if err := recover(); err != nil {
			stack := middleware.Stack(3)
			logger.LogErrorf("[Recovery] %s safeCompareFee panic recovered:\n%s\n%s", time.Now().Format("2006/01/02 - 15:04:05"), err, stack, false)
		}
	}()

	logger.SetLogId(requestID)
	compareFee(ctx, goApiResult, data, calculateData, requestID)
}

这个时候除了任何的错误都能够恢复。不会影响其他协程。但是这个时候每写一种就需写一个safe函数去做处理,需要在抽象一层出来。否则就会充斥copy。要对defer函数的处理就会需要各个地方修改。

版本三

func SafeGoroutineWithRequestID(f func(), requestID string) {

	defer func() {

		if err := recover(); err != nil {
			stack := Stack(3)
			logger.LogErrorf("[Recovery] %s %s panic recovered:\n%s\n%s", time.Now().Format("2006/01/02 - 15:04:05"), err, stack, false)
		}
	}()
	logger.SetLogId(requestID)
	f()
}

把函数当成参数传入进来,并且传入requestID。这时候就把recover 这一层抽象出来了。
但是问题来了。没有带参数的函数能够很好的放入到这个函数中。比如

func testPanic(){
    x, y := 100, 0
	c := x/y
	fmt.Println(c)
}

如果这个时候传入参数 y 是0 就会触发panic。但是这种函数没有入参。有入参又要怎么处理呢?

使用闭包的方式就可以处理了。
比如上面的comparefee 函数。

f := func() {
		compareV2ShippingFee(ctx, currentResult, data, calculateData, requestID)
	}
	go apiutils.SafeGoroutineWithRequestID(f2, requestID)

使用这种方式就饿能够达到目的。
至此,就能够愉快的开协程了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值