refactor(idgen): centralize negative ID handling via panic

Restore NextUint64ID() to uint64-only API so callers need no error
checks. Retry logic stays in idgen; after 3 negative values it panics
instead of returning 0, preventing silent NULL primary keys.
This commit is contained in:
ryan
2026-06-17 13:14:17 +08:00
parent 92dc6a59c0
commit 3a05e7f09c
11 changed files with 17 additions and 68 deletions
+4 -8
View File
@@ -6,7 +6,6 @@
package idgen
import (
"errors"
"fmt"
"log"
@@ -19,9 +18,6 @@ const epoch int64 = 1764547200000
const maxNegativeIDRetries = 3
// ErrNegativeSnowflakeID 表示 Snowflake 在重试后仍生成负值 ID。
var ErrNegativeSnowflakeID = errors.New("snowflake generated negative ID")
var node *snowflake.Node
func init() {
@@ -37,14 +33,14 @@ func init() {
}
// NextUint64ID 生成下一个分布式唯一 ID。
// 理论上不应出现负值;若出现则最多重试 maxNegativeIDRetries 次,仍失败则返回错误。
func NextUint64ID() (uint64, error) {
// 理论上不应出现负值;若出现则最多重试 maxNegativeIDRetries 次,仍失败则 panic。
func NextUint64ID() uint64 {
for attempt := 1; attempt <= maxNegativeIDRetries; attempt++ {
id := node.Generate().Int64()
if id >= 0 {
return uint64(id), nil
return uint64(id)
}
log.Printf("[Snowflake] generated negative ID: %d (attempt %d/%d)", id, attempt, maxNegativeIDRetries)
}
return 0, fmt.Errorf("%w: failed after %d attempts", ErrNegativeSnowflakeID, maxNegativeIDRetries)
panic(fmt.Sprintf("[Snowflake] generated negative ID after %d attempts", maxNegativeIDRetries))
}
+1 -3
View File
@@ -7,11 +7,9 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNextUint64ID(t *testing.T) {
id, err := NextUint64ID()
require.NoError(t, err)
id := NextUint64ID()
assert.NotZero(t, id)
}