与主协程协同:
feedADChan := make(chan struct{}, 1)
var feedAD *model.Advertisement
if req.WithFeedAD {
go func() {
var fetchAdvMaterialErr error
if fetchAdvMaterialErr, feedAD = service.FetchAdvMaterial(g, t.AdvertisementClient, ObjectPrefix,
advertisement.FetchAdvMaterialReq_ForFeed, "", "", req.UserId); fetchAdvMaterialErr != nil {
logger.GetLogger().Errorf("[handler] service.FetchAdvMaterial err: %v", fetchAdvMaterialErr)
}
// 释放主协程
feedADChan <- struct{}{}
}()
}
// 主程序代码
if req.WithFeedAD {
// 主协程等待
select {
case <-feedADChan:
// 拼接feedAD到contentList
if feedAD != nil {
service.SpliceFeedAd(feedAD, &contentList)
}
case <-time.After(2 * time.Second): // 超时控制
myLog.Errorf("[handler] fetchFeedAD goroutine timeout")
}
}
两协程互相协同:
func main() {
flag1 := make(chan int, 1)
flag2 := make(chan int, 1)
go opLog(flag1, flag2)
// 主协程等待
<-flag1
// 主协程代码
// 释放opLog协程
flag2 <- 1
}
func opLog(flag1 chan int, flag2 chan int) {
go func() {
ctx := context.Background()
myLog := logger.GetLogger()
// 获取原数据
originGroupInfo, opLogErr := mpClient.GetGroup(ctx, &mp.GetGroupReq{Id: req.Id})
if opLogErr != nil {
myLog.Errorf("[opLog] MpClient.GetGroup return originGroupInfo opLogErr: %v", opLogErr)
flag1 <- 1 // 获取原数据失败,释放主协程,opLog协程退出
return
}
originMpsInfo, opLogErr := mpClient.GetMps(ctx, &mp.GetMpsReq{Id: req.Id})
if opLogErr != nil {
myLog.Errorf("[opLog] MpClient.Gets return originMpsInfo opLogErr: %v", opLogErr)
flag1 <- 1 // 获取原数据失败,释放主协程,opLog协程退出
return
}
// 获取原数据成功,释放主协程
flag1 <- 1
// 等待主协程成功信号
select {
case <-flag2:
opLogMsg := fmt.Sprintf("(新增融合号:%s) (删除融合号:%s)", addBuf.String(), delBuf.String())
if originGroupInfo.Group.Name != req.Name {
opLogMsg = fmt.Sprintf("(原分组名称:%s, 新分组名称:%s)", originGroupInfo.Group.Name, req.Name) + opLogMsg
}
if opLogErr := common.DoOpLog(kfkPub, &operation_log.OpLog{
OperatorId: operatorId,
OpObject: message.OpLogMpGroup,
OpObjectId: req.Id,
OpDetail: fmt.Sprintf(common.AccountGroupModifyGroup, opLogMsg),
}); opLogErr != nil {
myLog.Errorf("[opLog] doOpLog opLogErr: %v", opLogErr)
}
case <-time.After(5 * time.Second): // 超时控制
myLog.Errorf("[opLog] goroutine timeout")
}
}()
}