登录
首页 >  Golang >  Go问答

是否有另一种安全的方法可以与其他库同时使用 ulid ?

来源:stackoverflow

时间:2024-02-10 10:09:23 262浏览 收藏

最近发现不少小伙伴都对Golang很感兴趣,所以今天继续给大家介绍Golang相关的知识,本文《是否有另一种安全的方法可以与其他库同时使用 ulid ?》主要内容涉及到等等知识点,希望能帮到你!当然如果阅读本文时存在不同想法,可以在评论中表达,但是请勿使用过激的措辞~

问题内容

我第一次尝试使用 ulid 包。

在他们的自述文件中他们说:

请注意 math 包中的 rand.rand 并发使用并不安全。 如果您想避免锁定 rand.source 的潜在争用,请为每个长期存在的 go 例程实例化一个或使用sync.pool,因为它在包级函数中经常观察到。

您能帮我理解这是什么意思以及如何编写安全代码以便与 ent 或 gqlgen 等库并发使用吗?

示例:我在应用程序中使用以下代码来生成新 id(有时甚至在同一毫秒内生成许多 id,这对于 ulid 来说很好)。

import (
  "math/rand"
  "time"

  "github.com/oklog/ulid/v2"
)

var defaultEntropySource *ulid.MonotonicEntropy

func init() {
  defaultEntropySource = ulid.Monotonic(rand.New(rand.NewSource(time.Now().UnixNano())), 0)
}

func NewID() string {
  return ulid.MustNew(ulid.Timestamp(time.Now()), defaultEntropySource).String()
}

这是使用该包的安全方法吗?


正确答案


不,这句话表明每个 rand.source 应该是 goroutine 本地的,你的 defaultentropysource rand.source 片段可能在多个 goroutine 之间共享。

如文档 New function 所示,您只需确保熵读取器对于并发使用是安全的,但 Monotonic 则不然。以下是实施文档建议的两种方法:

每次调用 newid() 创建一个单独的 rand.source,为每次调用 newid 分配一个新的熵

func newid() string {
    defaultentropysource := ulid.monotonic(rand.new(rand.newsource(time.now().unixnano())), 0)
    return ulid.mustnew(ulid.timestamp(time.now()), defaultentropysource).string()
}

Playground

与上面类似,但使用sync.pool可以重用之前分配的rand.sources

var entropyPool = sync.Pool{
    New: func() any {
        entropy := ulid.Monotonic(rand.New(rand.NewSource(time.Now().UnixNano())), 0)
        return entropy
    },
}

func NewID() string {
    e := entropyPool.Get().(*ulid.MonotonicEntropy)
    s := ulid.MustNew(ulid.Timestamp(time.Now()), e).String()
    entropyPool.Put(e)
    return s
}

Playground

终于介绍完啦!小伙伴们,这篇关于《是否有另一种安全的方法可以与其他库同时使用 ulid ?》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

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