为了账号安全,请及时绑定邮箱和手机立即绑定

同时等待两个结果并超时

同时等待两个结果并超时

Go
小怪兽爱吃肉 2023-07-10 16:30:35
使用案例我想对数据库并行运行两个查询,并在最多 600 毫秒后返回我当时获取的任何内容。我正在努力实现此要求的并发性。代码func (s *Service) GetCustomerStats(ctx context.Context, customerUUID string) *CustomerStats {    stats := &CustomerStats{        CustomerUUID: customerUUID,        Type:         "ERROR",        OrderCount:   "ERROR",    }    var wg sync.WaitGroup    var mu sync.Mutex    // Get order count    wg.Add(1)    go func() {        defer wg.Done()        orderCount, err := s.Storage.GetOrderCount(ctx, customerUUID)        if err != nil {            return        }        mu.Lock()        stats.OrderCount = strconv.Itoa(orderCount)        if orderCount == 0 {            stats.OrderCount = "NA"        }        mu.Unlock()    }()    // Get customer type    wg.Add(1)    go func() {        defer wg.Done()        type, err := s.Storage.GetCustomerType(ctx, customerUUID)        if err != nil {            return        }        mu.Lock()        stats.Type = strconv.Itoa(type)        mu.Unlock()    }()    wg.Wait()    return stats}问题我传递给该函数的上下文定义了 600 毫秒的超时。我将它传递给存储存储库,数据库驱动程序也使用它,但它不能保证它会在这段时间内做出响应,因为它确实会在后台安排一些重试。但是我必须确保该函数在传递的上下文超时(600 毫秒)内返回。我目前正在使用等待组来等待结果,但我不知道stats上下文完成后如何返回。基本上我正在寻找这样的东西。我的研究表明,我可能应该使用表明工作已完成的通道,但我不确定如何实现它,以便它是简单的代码。    select {    case wg.Wait()        return stats    case <-ctx.Done()        return stats    }
查看完整描述

1 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

您计划选择的方式看起来ctx.Done()是正确的。

在我看来,你处理可变状态的方式是错误的。


尝试这样的事情:


 var state = State{}

 select {

    case type <- typeChan

        stats.Type = type

        if (stats.OrderCount != nil) {

           return stats

        }

    case count <- countChan

        stats.OrderCount = count

        if (stats.Type != nil) {

           return stats

        }

    case <-ctx.Done()

        return stats

    }

现在你的函数应该是这样的:


go func() {        

    orderCount, err := s.Storage.GetOrderCount(ctx, customerUUID)

    if err != nil {

        return // Here you probably want to have errChan

    }


    if orderCount == 0 {

        countChan <- "NA"

    } else {

        countChan <- strconv.Itoa(orderCount)

    }        

}()

这一切都有点粗略,因为您的示例非常复杂,但应该为您提供遵循的方向。


查看完整回答
反对 回复 2023-07-10
  • 1 回答
  • 0 关注
  • 93 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信