Documentation
¶
Index ¶
Constants ¶
View Source
const ( // TimeBits is the number of bits in the timestamp reserved for time. Our // timestamp has millisecond precision and this setting gives us an epoch // of 34 years. As our reference time is the unix time, we are in epoch 1 // and the next epoch is ~2038 (which is when people with 32 bit time values // will be dealing with the unix epoc anyway) // // Notice that this setting is not configurable, though it is plausible we // could change it in the future. There is nothing 'impossible' about that // but it would be a very significant ask. TimeBits = 40 TimeShift = 64 - 40 TimeMask uint64 = ((1 << TimeBits) - 1) << TimeShift )
View Source
const ( // MaxSpins configures the maximum number of CAS cycles the id generator is // permitted. If the id generator exceeds this *and* the current sequence // counter is exhausted, the generator will error The generator can be // configured to allow *at most* this many spins. It is expect that this // value is used to configure the generator. MaxSpins = 100 Nanos = 1e6 )
View Source
const ( // MaxWorkerBits allowed per worker id or sequence counter MaxWorkerBits = 24 // MinWorkerBits allowed per worker id or sequence counter MinWorkerBits = 8 )
Variables ¶
View Source
var ( ErrWorkerBitRange = errors.New("the bit allocation for worker id and sequence bits overflows what is reserved for our timestamp") ErrOverloaded = errors.New("the id generator is over loaded for its configuration") ErrClockError = errors.New("the reading from system time doesn't make any realistic sense") ErrSequenceViolation = errors.New("the generator produced two consecutive values that violate either the monotonic or the uniqueness promises") // The nanosecond unix time overflows an int64 on 2262 // https://pkg.go.dev/time#Time.UnixNano. This is used for an error clause // that is essentially about catching serious clock configuration issues. UnixNanoEpochEndSentinel = time.Date(2261, 1, 1, 1, 1, 1, 1, time.UTC) // this is a year before the limit defined here )
View Source
var ( ErrBadWorkerCIDR = errors.New("provided worker CIDR is invalid") ErrBadPodIP = errors.New("pod ip invalid") ErrMaskRange = errors.New("the specified CIDR mask allows for to many or too few private ip addresses") )
View Source
var (
ErrMilliEpochOverflow = errors.New("our epoch allows for up to 2^40 milliseconds")
)
Functions ¶
func EpochTimeUTC ¶
func IDMilliSplit ¶
IDMilliSplit splits the milliseconds from the sequence uniqueness data without loss
Returns
milliseconds since epoch the machine id and sequence, guaranteed to be < 2^24
Types ¶
type Config ¶
type Config struct { // CommitmentEpoch determines our reference zero time with respect to unix // time It is expected that the service code defines this as a constant. // Note that this is a uint8 so that CommitmentEpoch * 2^TimeBits can not // overflow an int64. Each epoch is ~34 years and the correct current // configuration is 1, service code should make that a constant. CommitmentEpoch uint8 // WorkerCIDR ensures two pods can't generate the same snowflake id by // selecting bits from the pods private ip address. WorkerCIDR string // PodIP is the workload private ip address obtained via the Kubernetes PodIP string // AllowSpins should typically be set to the constant MaxSpins. If you are // un-familiar with how the generator works, just set this to MaxSpins. // Setting it to zero is supported, and effectively will cause the generator // to error when there is high contention. We do not support an infinite // number of spins, and for that reason we use a narrow type AllowSpins uint8 }
type IDState ¶
type IDState struct {
// contains filtered or unexported fields
}
func NewIDState ¶
func (*IDState) EpochStart ¶
func (*IDState) NextID ¶
NextID returns the next value in a time ordered, unique and monotonic series. If that property can't be assured the function will error. On error the caller should either sleep for millisecond or so, or error out. As the error condition is likely to hit due to high load, a sleep with jitter is considered the best approach as this will avoid thundering herd issues.
Click to show internal directories.
Click to hide internal directories.