| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package scrape
- import (
- "sync"
- "time"
- "github.com/opencost/opencost/core/pkg/clustercache"
- "github.com/opencost/opencost/core/pkg/log"
- "k8s.io/apimachinery/pkg/types"
- )
- // persistedIndexTTL is how long an index entry is retained after it was last seen in the cluster cache. It needs to
- // outlast the window where dependent objects (e.g. pods on a deleted node) remain in the cache after their referent
- // has been removed.
- const persistedIndexTTL = time.Hour
- type persistedIndexEntry struct {
- uid types.UID
- lastSeen time.Time
- }
- // persistedIndex retains key to UID mappings across scrapes. Objects are not always removed from the cluster cache in
- // dependency order, so an object can outlive the object it references by name (e.g. a pod whose node has already been
- // deleted). Retaining recently seen entries prevents these lookups from resolving to an empty UID, which would
- // overwrite the previously scraped value. A nil *persistedIndex performs no retention.
- type persistedIndex[K comparable] struct {
- name string
- lock sync.Mutex
- entries map[K]persistedIndexEntry
- }
- func newPersistedIndex[K comparable](name string) *persistedIndex[K] {
- return &persistedIndex[K]{
- name: name,
- entries: make(map[K]persistedIndexEntry),
- }
- }
- // update records the entries of current, which always take precedence over retained entries, evicts entries which
- // have not been seen within the ttl, and returns a new index containing current along with any retained entries.
- func (pi *persistedIndex[K]) update(current map[K]types.UID) map[K]types.UID {
- if pi == nil {
- return current
- }
- pi.lock.Lock()
- defer pi.lock.Unlock()
- now := time.Now()
- for key, uid := range current {
- pi.entries[key] = persistedIndexEntry{uid: uid, lastSeen: now}
- }
- result := make(map[K]types.UID, len(pi.entries))
- for key, entry := range pi.entries {
- if now.Sub(entry.lastSeen) > persistedIndexTTL {
- delete(pi.entries, key)
- continue
- }
- if _, ok := current[key]; !ok {
- log.Debugf("%s index: retaining UID '%s' for '%v' which is no longer in the cluster cache", pi.name, entry.uid, key)
- }
- result[key] = entry.uid
- }
- return result
- }
- // pvcKey is a composite key for a PersistentVolumeClaim (name + namespace).
- type pvcKey struct {
- name string
- namespace string
- }
- // buildNodeIndex returns a map from node name to UID.
- func buildNodeIndex(nodes []*clustercache.Node) map[string]types.UID {
- m := make(map[string]types.UID, len(nodes))
- for _, node := range nodes {
- m[node.Name] = node.UID
- }
- return m
- }
- // buildNamespaceIndex returns a map from namespace name to UID.
- func buildNamespaceIndex(namespaces []*clustercache.Namespace) map[string]types.UID {
- m := make(map[string]types.UID, len(namespaces))
- for _, ns := range namespaces {
- m[ns.Name] = ns.UID
- }
- return m
- }
- // buildPVCIndex returns a map from (name, namespace) to PVC UID.
- func buildPVCIndex(pvcs []*clustercache.PersistentVolumeClaim) map[pvcKey]types.UID {
- m := make(map[pvcKey]types.UID, len(pvcs))
- for _, pvc := range pvcs {
- m[pvcKey{name: pvc.Name, namespace: pvc.Namespace}] = pvc.UID
- }
- return m
- }
- // buildPVIndex returns a map from PV name to UID.
- func buildPVIndex(pvs []*clustercache.PersistentVolume) map[string]types.UID {
- m := make(map[string]types.UID, len(pvs))
- for _, pv := range pvs {
- m[pv.Name] = pv.UID
- }
- return m
- }
- // podKey is a composite key for a Pod (namespace + name).
- type podKey struct {
- namespace string
- name string
- }
- // buildPodIndex returns a map from (namespace, name) to Pod UID.
- func buildPodIndex(pods []*clustercache.Pod) map[podKey]types.UID {
- m := make(map[podKey]types.UID, len(pods))
- for _, pod := range pods {
- m[podKey{namespace: pod.Namespace, name: pod.Name}] = pod.UID
- }
- return m
- }
|