Merge pull request #18 from nishaad78/monotonic_clock
Use Monotonic clock
This commit is contained in:
commit
652d4f1b7f
27
snowflake.go
27
snowflake.go
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// Epoch is set to the twitter snowflake epoch of Nov 04 2010 01:42:54 UTC
|
||||
// Epoch is set to the twitter snowflake epoch of Nov 04 2010 01:42:54 UTC in milliseconds
|
||||
// You may customize this to set a different epoch for your application.
|
||||
Epoch int64 = 1288834974657
|
||||
|
||||
@ -77,10 +77,11 @@ var ErrInvalidBase32 = errors.New("invalid base32")
|
||||
// A Node struct holds the basic information needed for a snowflake generator
|
||||
// node
|
||||
type Node struct {
|
||||
mu sync.Mutex
|
||||
time int64
|
||||
node int64
|
||||
step int64
|
||||
mu sync.Mutex
|
||||
epoch time.Time
|
||||
time time.Duration
|
||||
node int64
|
||||
step int64
|
||||
|
||||
nodeMax int64
|
||||
nodeMask int64
|
||||
@ -119,6 +120,10 @@ func NewNode(node int64) (*Node, error) {
|
||||
return nil, errors.New("Node number must be between 0 and " + strconv.FormatInt(n.nodeMax, 10))
|
||||
}
|
||||
|
||||
var curTime = time.Now()
|
||||
// add time.Duration to curTime to make sure we use the monotonic clock if available
|
||||
n.epoch = curTime.Add(time.Unix(Epoch/1000, (Epoch%1000)*1000000).Sub(curTime))
|
||||
|
||||
return &n, nil
|
||||
}
|
||||
|
||||
@ -127,14 +132,14 @@ func (n *Node) Generate() ID {
|
||||
|
||||
n.mu.Lock()
|
||||
|
||||
now := time.Now().UnixNano() / 1000000
|
||||
now := time.Since(n.epoch)
|
||||
|
||||
if n.time == now {
|
||||
if now-n.time < time.Millisecond {
|
||||
n.step = (n.step + 1) & n.stepMask
|
||||
|
||||
if n.step == 0 {
|
||||
for now <= n.time {
|
||||
now = time.Now().UnixNano() / 1000000
|
||||
for now-n.time < time.Millisecond {
|
||||
now = time.Since(n.epoch)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -143,7 +148,7 @@ func (n *Node) Generate() ID {
|
||||
|
||||
n.time = now
|
||||
|
||||
r := ID((now-Epoch)<<n.timeShift |
|
||||
r := ID((now.Nanoseconds()/1000000)<<n.timeShift |
|
||||
(n.node << n.nodeShift) |
|
||||
(n.step),
|
||||
)
|
||||
@ -267,7 +272,7 @@ func (f ID) IntBytes() [8]byte {
|
||||
return b
|
||||
}
|
||||
|
||||
// Time returns an int64 unix timestamp of the snowflake ID time
|
||||
// Time returns an int64 unix timestamp in milliseconds of the snowflake ID time
|
||||
// DEPRECATED: the below function will be removed in a future release.
|
||||
func (f ID) Time() int64 {
|
||||
return (int64(f) >> timeShift) + Epoch
|
||||
|
Loading…
x
Reference in New Issue
Block a user