Ctrl K
ComunidadGuías…

pkg/k8score/dynamic_read.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package k8score

import (
	"slices"

	"k8s.io/apimachinery/pkg/runtime/schema"
)

// ReadWithSourceCheck runs one read and reports whether the same synced
// informers served its scope before and after it. The value and error are
// returned unchanged even when the read is not authoritative: a caller may
// accept a found object before sync, but a miss or list needs complete stores.
// With a nil cache the read still runs, but is never authoritative.
// It does not warm, wait, retry or validate the caller's access or connection.
func ReadWithSourceCheck[T any](cache *DynamicResourceCache, gvr schema.GroupVersionResource, namespace string, read func() (T, error)) (value T, authoritative bool, err error) {
	before, syncedBefore := cache.ReadSource(gvr, namespace)
	value, err = read()
	after, syncedAfter := cache.ReadSource(gvr, namespace)
	return value, syncedBefore && syncedAfter && before.Same(after), err
}

// DynamicReadSource identifies the informers serving reads of one GVR and
// namespace at a moment: their identity, not a snapshot of their objects.
// Starting a cluster-wide informer replaces a GVR's namespace informers
// inside the same cache, so two readiness checks that both pass can describe
// different informers; a read bracketed by two equal, synced sources was
// answered by stores that were complete throughout.
type DynamicReadSource struct {
	entries []*informerEntry
}

// Same reports whether s and other are the same informers, in any order.
func (s DynamicReadSource) Same(other DynamicReadSource) bool {
	if len(s.entries) != len(other.entries) {
		return false
	}
	for _, e := range s.entries {
		if !slices.Contains(other.entries, e) {
			return false
		}
	}
	return true
}

// ReadSource returns the informers serving reads of gvr in namespace now and
// whether they answer authoritatively, by IsNamespaceSynced's rules: namespace
// "" is a cluster-wide read, which only a cluster-wide informer answers. Both
// come from the same informers, so a replacement between them cannot mix them.
// A nil cache returns an empty source and false: never authoritative.
func (d *DynamicResourceCache) ReadSource(gvr schema.GroupVersionResource, namespace string) (DynamicReadSource, bool) {
	entries, ok := d.servedEntries(gvr, namespace)
	return DynamicReadSource{entries: entries}, ok
}