redis/id.go

49 lines
848 B
Go

package redis
import (
"fmt"
"sync"
"apigo.cc/go/id"
)
type idMaker struct {
rd *Redis
secCurrent uint64
secIndexMax uint64
secIndexNext uint64
lock sync.Mutex
}
func NewIDMaker(rd *Redis) *id.IDMaker {
im := &idMaker{rd: rd}
return id.NewIDMaker(im.makeSecIndex)
}
func (im *idMaker) makeSecIndex(sec uint64) uint64 {
im.lock.Lock()
defer im.lock.Unlock()
if im.secCurrent == sec && im.secIndexNext <= im.secIndexMax {
idx := im.secIndexNext
im.secIndexNext++
return idx
}
im.secCurrent = sec
key := fmt.Sprintf("_SecIdx_%d", sec)
// 每次 from Redis 预取 100 个序列号
max := uint64(im.rd.INCRBY(key, 100))
if max < 100 {
return 0
}
im.secIndexMax = max
im.secIndexNext = max - 99
idx := im.secIndexNext
im.secIndexNext++
if max <= 100 {
im.rd.EXPIRE(key, 10)
}
return idx
}