这是一个安全的方式来使用ulid与其他库并发吗?



我第一次尝试使用liid包。

在他们的自述文件中说:

请注意,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。源代码应该是本地的程序,您的defaultEntropySourcerand。源段可能在多个线程之间共享。

新函数,您只需要确保熵读取器对并发使用是安全的,但是Monotonic不是。下面是实现文档建议的两种方法:

创建单个rand。Source每次调用NewID(),为每次调用NewID分配一个新的熵

func NewID() string {
defaultEntropySource := ulid.Monotonic(rand.New(rand.NewSource(time.Now().UnixNano())), 0)
return ulid.MustNew(ulid.Timestamp(time.Now()), defaultEntropySource).String()
}

游乐场

和上面一样,但是使用同步。池可以重用以前分配的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
}

游乐场

最新更新