snowflakeid

package
v0.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2025 License: MIT Imports: 8 Imported by: 3

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 EpochMS

func EpochMS(epoch uint8) int64

func EpochTimeUTC

func EpochTimeUTC(epoch uint8) time.Time

func IDMilliSplit

func IDMilliSplit(id uint64) (uint64, uint32)

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

func IDTime

func IDTime(id uint64, epochStart time.Time) time.Time

func IDUnixMilli

func IDUnixMilli(id uint64, epoch uint8) (int64, error)

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 NewIDState(cfg Config) (*IDState, error)

func (*IDState) EpochStart

func (s *IDState) EpochStart() time.Time

func (*IDState) NextID

func (s *IDState) NextID() (uint64, error)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL