登录
首页 >  Golang >  Go问答

确保只对数据进行单一调用

来源:stackoverflow

时间:2024-02-28 21:30:24 425浏览 收藏

欢迎各位小伙伴来到golang学习网,相聚于此都是缘哈哈哈!今天我给大家带来《确保只对数据进行单一调用》,这篇文章主要讲到等等知识,如果你对Golang相关的知识非常感兴趣或者正在自学,都可以关注我,我会持续更新相关文章!当然,有什么建议也欢迎在评论留言提出!一起学习!

问题内容

我遇到了一个不寻常的情况:

  • 外部工具同时调用我的 api 的多个端点,
  • 所有端点都依赖于 s3 上某处托管的相同配置文件。

这可行,但它会同时多次获取相同的配置文件,而它只能获取一次。为了进行实验,我在这里有一个最小版本https://go.dev/play/p/nx-kidmprqx,它返回随机整数而不是执行 http 调用。

当前打印:

#2 start
#1 start
#1 result 5577006791947779410
#2 result 8674665223082153551
#3 start
#3 result 6129484611666145821

但我希望前两个调用返回相同的值,因为它们是同时完成的:

#2 start
#1 start
#1 result 5577006791947779410
#2 result 5577006791947779410
#3 start
#3 result 6129484611666145821

我正在努力想象一个解决方案。多个 goroutine 应该等待单个结果这一事实令人困惑。怎么可能做到呢?


正确答案


您可以使用 golang.org/x/sync/singleflight 中的 Group.Do 实现

// do executes and returns the results of the given function, making
// sure that only one execution is in-flight for a given key at a
// time. if a duplicate comes in, the duplicate caller waits for the
// original to complete and receives the same results.
// the return value shared indicates whether v was given to multiple callers.

修改示例以将函数的同步部分与通道操作分开:

func httpcall(run int) int {
    fmt.printf("#%d start\n", run)
    time.sleep(time.second)
    return rand.int()
}

您可以使用一个简单的包装函数来调用它来处理 singleflight.group 调用:

go func() {
    res, _, _ := g.Do("httpCall", func() (any, error) {
        return httpCall(1), nil
    })
    done <- res.(int)
}()

参见https://go.dev/play/p/ET0jNKEyg1_B

理论要掌握,实操不能落!以上关于《确保只对数据进行单一调用》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>