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  }