github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/util/ring.go (about) 1 package util 2 3 import ( 4 "hash/fnv" 5 6 "github.com/go-kit/log/level" 7 "github.com/grafana/dskit/ring" 8 9 util_log "github.com/grafana/loki/pkg/util/log" 10 ) 11 12 // TokenFor generates a token used for finding ingesters from ring 13 func TokenFor(userID, labels string) uint32 { 14 h := fnv.New32() 15 _, _ = h.Write([]byte(userID)) 16 _, _ = h.Write([]byte(labels)) 17 return h.Sum32() 18 } 19 20 // IsInReplicationSet will query the provided ring for the provided key 21 // and see if the provided address is in the resulting ReplicationSet 22 func IsInReplicationSet(r ring.ReadRing, ringKey uint32, address string) (bool, error) { 23 bufDescs, bufHosts, bufZones := ring.MakeBuffersForGet() 24 rs, err := r.Get(ringKey, ring.Write, bufDescs, bufHosts, bufZones) 25 if err != nil { 26 return false, err 27 } 28 29 addrs := rs.GetAddresses() 30 for _, a := range addrs { 31 if a == address { 32 return true, nil 33 } 34 } 35 return false, nil 36 } 37 38 // IsAssignedKey replies wether the given instance address is in the ReplicationSet responsible for the given key or not, based on the tokens. 39 // 40 // The result will be defined based on the tokens assigned to each ring component, queried through the ring client. 41 func IsAssignedKey(ringClient ring.ReadRing, instanceAddress string, key string) bool { 42 token := TokenFor(key, "" /* labels */) 43 inSet, err := IsInReplicationSet(ringClient, token, instanceAddress) 44 if err != nil { 45 level.Error(util_log.Logger).Log("msg", "error checking if key is in replicationset", "error", err, "key", key) 46 return false 47 } 48 return inSet 49 }