mirror of
https://dev.azure.com/schwarzit/schwarzit.stackit-public/_git/audit-go
synced 2026-02-08 00:57:24 +00:00
Concurrent invocations on the SequenceNumberGenerator can lead to gaps and duplicate sequence numbers. To fix the issue an internal "backlog" is added as a buffer. If a new number is requested the "backlog" is checked first before creating a new number. The "host" HTTP-Header is filtered out hide internal information. The following build dependencies have been updated: - Go has been updated to version 1.23.3. - Golanglint-ci has been updated to version v1.62.0. - Buf has been updated to version v1.46.0 The following library dependencies have been updated: - go.opentelemetry.io/otel has been updated to version v1.32.0 - go.opentelemetry.io/otel/trace has been updated to version v1.32.0 Related work items: #696569
60 lines
1.6 KiB
Go
60 lines
1.6 KiB
Go
package utils
|
|
|
|
import (
|
|
"slices"
|
|
"sync"
|
|
)
|
|
|
|
// SequenceNumberGenerator can be used to generate increasing numbers.
|
|
type SequenceNumberGenerator interface {
|
|
|
|
// Next returns the next number
|
|
Next() uint64
|
|
|
|
// Revert can be used to revert a specific number (e.g. in case of an error)
|
|
Revert(uint64)
|
|
}
|
|
|
|
// DefaultSequenceNumberGenerator is a mutex protected implementation of SequenceNumberGenerator
|
|
type DefaultSequenceNumberGenerator struct {
|
|
backlog []uint64
|
|
sequenceNumber uint64
|
|
sequenceNumberLock sync.Mutex
|
|
}
|
|
|
|
// NewDefaultSequenceNumberGenerator returns an instance of DefaultSequenceNumberGenerator as pointer
|
|
// of SequenceNumberGenerator.
|
|
func NewDefaultSequenceNumberGenerator() *SequenceNumberGenerator {
|
|
var generator SequenceNumberGenerator = &DefaultSequenceNumberGenerator{
|
|
backlog: make([]uint64, 0),
|
|
sequenceNumber: 0,
|
|
sequenceNumberLock: sync.Mutex{},
|
|
}
|
|
return &generator
|
|
}
|
|
|
|
// Next implements SequenceNumberGenerator.Next
|
|
func (g *DefaultSequenceNumberGenerator) Next() uint64 {
|
|
g.sequenceNumberLock.Lock()
|
|
defer g.sequenceNumberLock.Unlock()
|
|
var next uint64
|
|
if len(g.backlog) == 0 {
|
|
next = g.sequenceNumber
|
|
g.sequenceNumber += 1
|
|
} else {
|
|
next = g.backlog[0]
|
|
g.backlog = g.backlog[1:]
|
|
}
|
|
return next
|
|
}
|
|
|
|
// Revert implements SequenceNumberGenerator.Revert
|
|
func (g *DefaultSequenceNumberGenerator) Revert(value uint64) {
|
|
g.sequenceNumberLock.Lock()
|
|
defer g.sequenceNumberLock.Unlock()
|
|
if value == g.sequenceNumber-1 {
|
|
g.sequenceNumber -= 1
|
|
} else if !slices.Contains(g.backlog, value) {
|
|
g.backlog = append(g.backlog, value)
|
|
}
|
|
}
|