golang-yitisheng-server/server/common/id_utils.go

85 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package common
import (
"errors"
"strconv"
"sync"
"server/common/snowflake"
)
var (
defaultSnowflake *snowflake.Snowflake
once sync.Once
)
// InitGenerator 初始化雪花算法生成器
// workerId: 工作机器ID (0 ~ 31)
// datacenterId: 数据中心ID (0 ~ 31)
// 如果不需要区分数据中心,可以将 datacenterId 设置为 0
func InitGenerator(workerId, datacenterId int64) error {
// 先校验参数
if workerId < 0 || workerId > 31 {
return errors.New("workerId must be between 0 and 31")
}
if datacenterId < 0 || datacenterId > 31 {
return errors.New("datacenterId must be between 0 and 31")
}
// 执行初始化
once.Do(func() {
var err error
defaultSnowflake, err = snowflake.NewSnowflake(workerId, datacenterId)
if err != nil {
panic("InitGenerator failed: " + err.Error())
}
})
return nil
}
// InitGeneratorWithWorkerID 仅使用 workerId 初始化(兼容旧版本)
// datacenterId 默认为 0
func InitGeneratorWithWorkerID(workerID int64) error {
return InitGenerator(workerID, 0)
}
// getInstance 获取单例实例
func getInstance() *snowflake.Snowflake {
once.Do(func() {
// 默认值workerId=1, datacenterId=0
var err error
defaultSnowflake, err = snowflake.NewSnowflake(1, 0)
if err != nil {
// 默认参数如果还失败,直接 panic
panic("Snowflake getInstance failed: " + err.Error())
}
})
// 防御性编程:如果 once.Do 已经执行过(例如被 InitGenerator 执行了),
// 但因为 panic 或其他异常导致 defaultSnowflake 仍为 nil这里进行补救
if defaultSnowflake == nil {
// 此时忽略 sync.Once直接强制初始化防止 nil pointer crash
// 使用默认安全值 (1, 0)
defaultSnowflake, _ = snowflake.NewSnowflake(1, 0)
}
return defaultSnowflake
}
// GenerateLongID 生成 64 位整型 ID
func GenerateLongID() int64 {
id, err := getInstance().NextId()
if err != nil {
// 极端情况:时间回拨
// 返回 0 或使用时间戳作为备用方案
panic("GenerateLongID failed: " + err.Error())
}
return id
}
// GenerateStringID 生成字符串 ID
func GenerateStringID() string {
return strconv.FormatInt(GenerateLongID(), 10)
}