Added the new and distributed NumGen, which replaces the old one. The old implementation was based on a master server.
72 lines
1.6 KiB
Go
72 lines
1.6 KiB
Go
package NumGen
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// Function to generate a unique ID.
|
|
func GetUniqueID() (id int64) {
|
|
|
|
// Exklusive access:
|
|
genLock.Lock()
|
|
defer genLock.Unlock()
|
|
incremented := false
|
|
|
|
Retry:
|
|
|
|
// Read the current time
|
|
t1 := time.Now().UTC()
|
|
t1Milliseconds := int(float64(t1.Nanosecond()) / 1000000.0)
|
|
|
|
// Calculate the difference to the last generated number:
|
|
diff := t1.Sub(genCurrentTime)
|
|
|
|
// Case 1: Huge difference?
|
|
if diff.Seconds() > 1.0 {
|
|
genCurrentTime = t1
|
|
genCurrentMillisecond = t1Milliseconds
|
|
genCurrentMillisecondCounter = 0
|
|
id = generateUniqueID(genCurrentMillisecondCounter)
|
|
return
|
|
}
|
|
|
|
/*
|
|
The fist case is necessary, because the same count of milliseconds
|
|
can occur every second, etc. ;-) Therefore, a check only by the
|
|
milliseconds is not sufficient.
|
|
*/
|
|
|
|
// Case 2: Small difference?
|
|
if t1Milliseconds != genCurrentMillisecond {
|
|
genCurrentTime = t1
|
|
genCurrentMillisecond = t1Milliseconds
|
|
genCurrentMillisecondCounter = 0
|
|
id = generateUniqueID(genCurrentMillisecondCounter)
|
|
return
|
|
}
|
|
|
|
//
|
|
// Case 3: Another number must be generated at the same millisecond!
|
|
//
|
|
|
|
if incremented == false {
|
|
genCurrentMillisecondCounter++
|
|
incremented = true
|
|
}
|
|
|
|
// Case 3.1: More than 1000 numbers are generated at one millisecond?
|
|
if genCurrentMillisecondCounter > 999 {
|
|
// This is not possible with the current algorithm!
|
|
// Therefore, we force this and all other request to wait some time:
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
// Try it again:
|
|
goto Retry
|
|
// Case 3.2: Less than 1000 numbers are generated at one millisecond?
|
|
} else {
|
|
// This case is fine:
|
|
id = generateUniqueID(genCurrentMillisecondCounter)
|
|
return
|
|
}
|
|
}
|