mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-07 02:07:58 +00:00
Update custom-metrics-apiserver and metrics-server
This commit is contained in:
parent
4c673534f2
commit
b480e45a67
915 changed files with 63694 additions and 106514 deletions
196
vendor/k8s.io/client-go/tools/cache/shared_informer.go
generated
vendored
196
vendor/k8s.io/client-go/tools/cache/shared_informer.go
generated
vendored
|
|
@ -21,11 +21,11 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/utils/buffer"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
|
@ -46,15 +46,6 @@ import (
|
|||
// An object state is either "absent" or present with a
|
||||
// ResourceVersion and other appropriate content.
|
||||
//
|
||||
// A SharedInformer gets object states from apiservers using a
|
||||
// sequence of LIST and WATCH operations. Through this sequence the
|
||||
// apiservers provide a sequence of "collection states" to the
|
||||
// informer, where each collection state defines the state of every
|
||||
// object of the collection. No promise --- beyond what is implied by
|
||||
// other remarks here --- is made about how one informer's sequence of
|
||||
// collection states relates to a different informer's sequence of
|
||||
// collection states.
|
||||
//
|
||||
// A SharedInformer maintains a local cache, exposed by GetStore() and
|
||||
// by GetIndexer() in the case of an indexed informer, of the state of
|
||||
// each relevant object. This cache is eventually consistent with the
|
||||
|
|
@ -67,10 +58,17 @@ import (
|
|||
// To be formally complete, we say that the absent state meets any
|
||||
// restriction by label selector or field selector.
|
||||
//
|
||||
// For a given informer and relevant object ID X, the sequence of
|
||||
// states that appears in the informer's cache is a subsequence of the
|
||||
// states authoritatively associated with X. That is, some states
|
||||
// might never appear in the cache but ordering among the appearing
|
||||
// states is correct. Note, however, that there is no promise about
|
||||
// ordering between states seen for different objects.
|
||||
//
|
||||
// The local cache starts out empty, and gets populated and updated
|
||||
// during `Run()`.
|
||||
//
|
||||
// As a simple example, if a collection of objects is henceforeth
|
||||
// As a simple example, if a collection of objects is henceforth
|
||||
// unchanging, a SharedInformer is created that links to that
|
||||
// collection, and that SharedInformer is `Run()` then that
|
||||
// SharedInformer's cache eventually holds an exact copy of that
|
||||
|
|
@ -91,6 +89,10 @@ import (
|
|||
// a given object, and `SplitMetaNamespaceKey(key)` to split a key
|
||||
// into its constituent parts.
|
||||
//
|
||||
// Every query against the local cache is answered entirely from one
|
||||
// snapshot of the cache's state. Thus, the result of a `List` call
|
||||
// will not contain two entries with the same namespace and name.
|
||||
//
|
||||
// A client is identified here by a ResourceEventHandler. For every
|
||||
// update to the SharedInformer's local cache and for every client
|
||||
// added before `Run()`, eventually either the SharedInformer is
|
||||
|
|
@ -106,7 +108,16 @@ import (
|
|||
// and index updates happen before such a prescribed notification.
|
||||
// For a given SharedInformer and client, the notifications are
|
||||
// delivered sequentially. For a given SharedInformer, client, and
|
||||
// object ID, the notifications are delivered in order.
|
||||
// object ID, the notifications are delivered in order. Because
|
||||
// `ObjectMeta.UID` has no role in identifying objects, it is possible
|
||||
// that when (1) object O1 with ID (e.g. namespace and name) X and
|
||||
// `ObjectMeta.UID` U1 in the SharedInformer's local cache is deleted
|
||||
// and later (2) another object O2 with ID X and ObjectMeta.UID U2 is
|
||||
// created the informer's clients are not notified of (1) and (2) but
|
||||
// rather are notified only of an update from O1 to O2. Clients that
|
||||
// need to detect such cases might do so by comparing the `ObjectMeta.UID`
|
||||
// field of the old and the new object in the code that handles update
|
||||
// notifications (i.e. `OnUpdate` method of ResourceEventHandler).
|
||||
//
|
||||
// A client must process each notification promptly; a SharedInformer
|
||||
// is not engineered to deal well with a large backlog of
|
||||
|
|
@ -114,11 +125,6 @@ import (
|
|||
// to something else, for example through a
|
||||
// `client-go/util/workqueue`.
|
||||
//
|
||||
// Each query to an informer's local cache --- whether a single-object
|
||||
// lookup, a list operation, or a use of one of its indices --- is
|
||||
// answered entirely from one of the collection states received by
|
||||
// that informer.
|
||||
//
|
||||
// A delete notification exposes the last locally known non-absent
|
||||
// state, except that its ResourceVersion is replaced with a
|
||||
// ResourceVersion in which the object is actually absent.
|
||||
|
|
@ -128,14 +134,23 @@ type SharedInformer interface {
|
|||
// between different handlers.
|
||||
AddEventHandler(handler ResourceEventHandler)
|
||||
// AddEventHandlerWithResyncPeriod adds an event handler to the
|
||||
// shared informer using the specified resync period. The resync
|
||||
// operation consists of delivering to the handler a create
|
||||
// notification for every object in the informer's local cache; it
|
||||
// does not add any interactions with the authoritative storage.
|
||||
// shared informer with the requested resync period; zero means
|
||||
// this handler does not care about resyncs. The resync operation
|
||||
// consists of delivering to the handler an update notification
|
||||
// for every object in the informer's local cache; it does not add
|
||||
// any interactions with the authoritative storage. Some
|
||||
// informers do no resyncs at all, not even for handlers added
|
||||
// with a non-zero resyncPeriod. For an informer that does
|
||||
// resyncs, and for each handler that requests resyncs, that
|
||||
// informer develops a nominal resync period that is no shorter
|
||||
// than the requested period but may be longer. The actual time
|
||||
// between any two resyncs may be longer than the nominal period
|
||||
// because the implementation takes time to do work and there may
|
||||
// be competing load and scheduling noise.
|
||||
AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration)
|
||||
// GetStore returns the informer's local cache as a Store.
|
||||
GetStore() Store
|
||||
// GetController gives back a synthetic interface that "votes" to start the informer
|
||||
// GetController is deprecated, it does nothing useful
|
||||
GetController() Controller
|
||||
// Run starts and runs the shared informer, returning after it stops.
|
||||
// The informer will be stopped when stopCh is closed.
|
||||
|
|
@ -159,21 +174,32 @@ type SharedIndexInformer interface {
|
|||
}
|
||||
|
||||
// NewSharedInformer creates a new instance for the listwatcher.
|
||||
func NewSharedInformer(lw ListerWatcher, objType runtime.Object, resyncPeriod time.Duration) SharedInformer {
|
||||
return NewSharedIndexInformer(lw, objType, resyncPeriod, Indexers{})
|
||||
func NewSharedInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration) SharedInformer {
|
||||
return NewSharedIndexInformer(lw, exampleObject, defaultEventHandlerResyncPeriod, Indexers{})
|
||||
}
|
||||
|
||||
// NewSharedIndexInformer creates a new instance for the listwatcher.
|
||||
func NewSharedIndexInformer(lw ListerWatcher, objType runtime.Object, defaultEventHandlerResyncPeriod time.Duration, indexers Indexers) SharedIndexInformer {
|
||||
// The created informer will not do resyncs if the given
|
||||
// defaultEventHandlerResyncPeriod is zero. Otherwise: for each
|
||||
// handler that with a non-zero requested resync period, whether added
|
||||
// before or after the informer starts, the nominal resync period is
|
||||
// the requested resync period rounded up to a multiple of the
|
||||
// informer's resync checking period. Such an informer's resync
|
||||
// checking period is established when the informer starts running,
|
||||
// and is the maximum of (a) the minimum of the resync periods
|
||||
// requested before the informer starts and the
|
||||
// defaultEventHandlerResyncPeriod given here and (b) the constant
|
||||
// `minimumResyncPeriod` defined in this file.
|
||||
func NewSharedIndexInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration, indexers Indexers) SharedIndexInformer {
|
||||
realClock := &clock.RealClock{}
|
||||
sharedIndexInformer := &sharedIndexInformer{
|
||||
processor: &sharedProcessor{clock: realClock},
|
||||
indexer: NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, indexers),
|
||||
listerWatcher: lw,
|
||||
objectType: objType,
|
||||
objectType: exampleObject,
|
||||
resyncCheckPeriod: defaultEventHandlerResyncPeriod,
|
||||
defaultEventHandlerResyncPeriod: defaultEventHandlerResyncPeriod,
|
||||
cacheMutationDetector: NewCacheMutationDetector(fmt.Sprintf("%T", objType)),
|
||||
cacheMutationDetector: NewCacheMutationDetector(fmt.Sprintf("%T", exampleObject)),
|
||||
clock: realClock,
|
||||
}
|
||||
return sharedIndexInformer
|
||||
|
|
@ -228,6 +254,19 @@ func WaitForCacheSync(stopCh <-chan struct{}, cacheSyncs ...InformerSynced) bool
|
|||
return true
|
||||
}
|
||||
|
||||
// `*sharedIndexInformer` implements SharedIndexInformer and has three
|
||||
// main components. One is an indexed local cache, `indexer Indexer`.
|
||||
// The second main component is a Controller that pulls
|
||||
// objects/notifications using the ListerWatcher and pushes them into
|
||||
// a DeltaFIFO --- whose knownObjects is the informer's local cache
|
||||
// --- while concurrently Popping Deltas values from that fifo and
|
||||
// processing them with `sharedIndexInformer::HandleDeltas`. Each
|
||||
// invocation of HandleDeltas, which is done with the fifo's lock
|
||||
// held, processes each Delta in turn. For each Delta this both
|
||||
// updates the local cache and stuffs the relevant notification into
|
||||
// the sharedProcessor. The third main component is that
|
||||
// sharedProcessor, which is responsible for relaying those
|
||||
// notifications to each of the informer's clients.
|
||||
type sharedIndexInformer struct {
|
||||
indexer Indexer
|
||||
controller Controller
|
||||
|
|
@ -235,9 +274,13 @@ type sharedIndexInformer struct {
|
|||
processor *sharedProcessor
|
||||
cacheMutationDetector MutationDetector
|
||||
|
||||
// This block is tracked to handle late initialization of the controller
|
||||
listerWatcher ListerWatcher
|
||||
objectType runtime.Object
|
||||
|
||||
// objectType is an example object of the type this informer is
|
||||
// expected to handle. Only the type needs to be right, except
|
||||
// that when that is `unstructured.Unstructured` the object's
|
||||
// `"apiVersion"` and `"kind"` must also be right.
|
||||
objectType runtime.Object
|
||||
|
||||
// resyncCheckPeriod is how often we want the reflector's resync timer to fire so it can call
|
||||
// shouldResync to check if any of our listeners need a resync.
|
||||
|
|
@ -293,7 +336,10 @@ type deleteNotification struct {
|
|||
func (s *sharedIndexInformer) Run(stopCh <-chan struct{}) {
|
||||
defer utilruntime.HandleCrash()
|
||||
|
||||
fifo := NewDeltaFIFO(MetaNamespaceKeyFunc, s.indexer)
|
||||
fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{
|
||||
KnownObjects: s.indexer,
|
||||
EmitDeltaTypeReplaced: true,
|
||||
})
|
||||
|
||||
cfg := &Config{
|
||||
Queue: fifo,
|
||||
|
|
@ -452,19 +498,33 @@ func (s *sharedIndexInformer) HandleDeltas(obj interface{}) error {
|
|||
// from oldest to newest
|
||||
for _, d := range obj.(Deltas) {
|
||||
switch d.Type {
|
||||
case Sync, Added, Updated:
|
||||
isSync := d.Type == Sync
|
||||
case Sync, Replaced, Added, Updated:
|
||||
s.cacheMutationDetector.AddObject(d.Object)
|
||||
if old, exists, err := s.indexer.Get(d.Object); err == nil && exists {
|
||||
if err := s.indexer.Update(d.Object); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isSync := false
|
||||
switch {
|
||||
case d.Type == Sync:
|
||||
// Sync events are only propagated to listeners that requested resync
|
||||
isSync = true
|
||||
case d.Type == Replaced:
|
||||
if accessor, err := meta.Accessor(d.Object); err == nil {
|
||||
if oldAccessor, err := meta.Accessor(old); err == nil {
|
||||
// Replaced events that didn't change resourceVersion are treated as resync events
|
||||
// and only propagated to listeners that requested resync
|
||||
isSync = accessor.GetResourceVersion() == oldAccessor.GetResourceVersion()
|
||||
}
|
||||
}
|
||||
}
|
||||
s.processor.distribute(updateNotification{oldObj: old, newObj: d.Object}, isSync)
|
||||
} else {
|
||||
if err := s.indexer.Add(d.Object); err != nil {
|
||||
return err
|
||||
}
|
||||
s.processor.distribute(addNotification{newObj: d.Object}, isSync)
|
||||
s.processor.distribute(addNotification{newObj: d.Object}, false)
|
||||
}
|
||||
case Deleted:
|
||||
if err := s.indexer.Delete(d.Object); err != nil {
|
||||
|
|
@ -476,6 +536,12 @@ func (s *sharedIndexInformer) HandleDeltas(obj interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// sharedProcessor has a collection of processorListener and can
|
||||
// distribute a notification object to its listeners. There are two
|
||||
// kinds of distribute operations. The sync distributions go to a
|
||||
// subset of the listeners that (a) is recomputed in the occasional
|
||||
// calls to shouldResync and (b) every listener is initially put in.
|
||||
// The non-sync distributions go to every listener.
|
||||
type sharedProcessor struct {
|
||||
listenersStarted bool
|
||||
listenersLock sync.RWMutex
|
||||
|
|
@ -567,6 +633,17 @@ func (p *sharedProcessor) resyncCheckPeriodChanged(resyncCheckPeriod time.Durati
|
|||
}
|
||||
}
|
||||
|
||||
// processorListener relays notifications from a sharedProcessor to
|
||||
// one ResourceEventHandler --- using two goroutines, two unbuffered
|
||||
// channels, and an unbounded ring buffer. The `add(notification)`
|
||||
// function sends the given notification to `addCh`. One goroutine
|
||||
// runs `pop()`, which pumps notifications from `addCh` to `nextCh`
|
||||
// using storage in the ring buffer while `nextCh` is not keeping up.
|
||||
// Another goroutine runs `run()`, which receives notifications from
|
||||
// `nextCh` and synchronously invokes the appropriate handler method.
|
||||
//
|
||||
// processorListener also keeps track of the adjusted requested resync
|
||||
// period of the listener.
|
||||
type processorListener struct {
|
||||
nextCh chan interface{}
|
||||
addCh chan interface{}
|
||||
|
|
@ -580,11 +657,22 @@ type processorListener struct {
|
|||
// we should try to do something better.
|
||||
pendingNotifications buffer.RingGrowing
|
||||
|
||||
// requestedResyncPeriod is how frequently the listener wants a full resync from the shared informer
|
||||
// requestedResyncPeriod is how frequently the listener wants a
|
||||
// full resync from the shared informer, but modified by two
|
||||
// adjustments. One is imposing a lower bound,
|
||||
// `minimumResyncPeriod`. The other is another lower bound, the
|
||||
// sharedProcessor's `resyncCheckPeriod`, that is imposed (a) only
|
||||
// in AddEventHandlerWithResyncPeriod invocations made after the
|
||||
// sharedProcessor starts and (b) only if the informer does
|
||||
// resyncs at all.
|
||||
requestedResyncPeriod time.Duration
|
||||
// resyncPeriod is how frequently the listener wants a full resync from the shared informer. This
|
||||
// value may differ from requestedResyncPeriod if the shared informer adjusts it to align with the
|
||||
// informer's overall resync check period.
|
||||
// resyncPeriod is the threshold that will be used in the logic
|
||||
// for this listener. This value differs from
|
||||
// requestedResyncPeriod only when the sharedIndexInformer does
|
||||
// not do resyncs, in which case the value here is zero. The
|
||||
// actual time between resyncs depends on when the
|
||||
// sharedProcessor's `shouldResync` function is invoked and when
|
||||
// the sharedIndexInformer processes `Sync` type Delta objects.
|
||||
resyncPeriod time.Duration
|
||||
// nextResync is the earliest time the listener should get a full resync
|
||||
nextResync time.Time
|
||||
|
|
@ -648,29 +736,21 @@ func (p *processorListener) run() {
|
|||
// delivering again.
|
||||
stopCh := make(chan struct{})
|
||||
wait.Until(func() {
|
||||
// this gives us a few quick retries before a long pause and then a few more quick retries
|
||||
err := wait.ExponentialBackoff(retry.DefaultRetry, func() (bool, error) {
|
||||
for next := range p.nextCh {
|
||||
switch notification := next.(type) {
|
||||
case updateNotification:
|
||||
p.handler.OnUpdate(notification.oldObj, notification.newObj)
|
||||
case addNotification:
|
||||
p.handler.OnAdd(notification.newObj)
|
||||
case deleteNotification:
|
||||
p.handler.OnDelete(notification.oldObj)
|
||||
default:
|
||||
utilruntime.HandleError(fmt.Errorf("unrecognized notification: %T", next))
|
||||
}
|
||||
for next := range p.nextCh {
|
||||
switch notification := next.(type) {
|
||||
case updateNotification:
|
||||
p.handler.OnUpdate(notification.oldObj, notification.newObj)
|
||||
case addNotification:
|
||||
p.handler.OnAdd(notification.newObj)
|
||||
case deleteNotification:
|
||||
p.handler.OnDelete(notification.oldObj)
|
||||
default:
|
||||
utilruntime.HandleError(fmt.Errorf("unrecognized notification: %T", next))
|
||||
}
|
||||
// the only way to get here is if the p.nextCh is empty and closed
|
||||
return true, nil
|
||||
})
|
||||
|
||||
// the only way to get here is if the p.nextCh is empty and closed
|
||||
if err == nil {
|
||||
close(stopCh)
|
||||
}
|
||||
}, 1*time.Minute, stopCh)
|
||||
// the only way to get here is if the p.nextCh is empty and closed
|
||||
close(stopCh)
|
||||
}, 1*time.Second, stopCh)
|
||||
}
|
||||
|
||||
// shouldResync deterimines if the listener needs a resync. If the listener's resyncPeriod is 0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue