Files
Joe ElliottandGitHub 361c8f7e5e Fix GRPC/HTTP/TLS (#3300)
* first pass - working

Signed-off-by: Joe Elliott <[email protected]>

* refactor

Signed-off-by: Joe Elliott <[email protected]>

* working?

Signed-off-by: Joe Elliott <[email protected]>

* vendor

Signed-off-by: Joe Elliott <[email protected]>

* integration test

Signed-off-by: Joe Elliott <[email protected]>

* updated go.mod to latest

Signed-off-by: Joe Elliott <[email protected]>

* cleanup

Signed-off-by: Joe Elliott <[email protected]>

* changelog

Signed-off-by: Joe Elliott <[email protected]>

* lint

Signed-off-by: Joe Elliott <[email protected]>

* update servless mods

Signed-off-by: Joe Elliott <[email protected]>

* satisfy interface updates

Signed-off-by: Joe Elliott <[email protected]>

* lint

Signed-off-by: Joe Elliott <[email protected]>

---------

Signed-off-by: Joe Elliott <[email protected]>
2024-01-17 13:33:12 -05:00

80 lines
2.1 KiB
Go

package ring
import (
"math/rand"
"sort"
"sync"
"time"
)
type TokenGenerator interface {
// GenerateTokens generates at most requestedTokensCount unique tokens, none of which clashes with
// the given allTakenTokens, representing the set of all tokens currently present in the ring.
// Generated tokens are sorted.
GenerateTokens(requestedTokensCount int, allTakenTokens []uint32) Tokens
// CanJoin checks whether the instance owning this TokenGenerator can join the set of the given instances satisfies,
// and fails if it is not possible.
CanJoin(instances map[string]InstanceDesc) error
// CanJoinEnabled returns true if the instance owning this TokenGenerator should perform the CanJoin check before
// it tries to join the ring.
CanJoinEnabled() bool
}
type RandomTokenGenerator struct {
m sync.Mutex
r *rand.Rand
}
func NewRandomTokenGenerator() *RandomTokenGenerator {
return &RandomTokenGenerator{r: rand.New(rand.NewSource(time.Now().UnixNano()))}
}
func NewRandomTokenGeneratorWithSeed(seed int64) *RandomTokenGenerator {
return &RandomTokenGenerator{r: rand.New(rand.NewSource(seed))}
}
// GenerateTokens generates at most requestedTokensCount unique random tokens, none of which clashes with
// the given allTakenTokens, representing the set of all tokens currently present in the ring.
// Generated tokens are sorted.
func (t *RandomTokenGenerator) GenerateTokens(requestedTokensCount int, allTakenTokens []uint32) Tokens {
if requestedTokensCount <= 0 {
return []uint32{}
}
used := make(map[uint32]bool, len(allTakenTokens))
for _, v := range allTakenTokens {
used[v] = true
}
tokens := make([]uint32, 0, requestedTokensCount)
for i := 0; i < requestedTokensCount; {
t.m.Lock()
candidate := t.r.Uint32()
t.m.Unlock()
if used[candidate] {
continue
}
used[candidate] = true
tokens = append(tokens, candidate)
i++
}
// Ensure returned tokens are sorted.
sort.Slice(tokens, func(i, j int) bool {
return tokens[i] < tokens[j]
})
return tokens
}
func (t *RandomTokenGenerator) CanJoin(_ map[string]InstanceDesc) error {
return nil
}
func (t *RandomTokenGenerator) CanJoinEnabled() bool {
return false
}