Change:
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks! If the matter is security related, please disclose it privately via --What happened: Not observed yet, but deduced from analyzing the code. If a k/apiserver/pkg/util/flowcontrol/fairqueuing.QueueSet, whose metrics.TimedObserverPair is a pair of k/apiserver/pkg/util/flowcontrol/metrics.sampleAndWaterMarkHistograms, gets zero activity for a long while and then gets some activity, then the loop at will go through a lot of iterations, and do so with a lock held. What you expected to happen: No big hiccups in any scenario. How to reproduce it (as minimally and precisely as possible): Anything else we need to know?: Environment: Kubernetes version (use ): branch Cloud provider or hardware configuration: OS (e.g: ): Kernel (e.g. ): Install tools: Network plugin and version (if this is a network-related bug): Others:
/assign

Discussion:
if s.isPostStartHookRegistered(priorityAndFairnessConfigConsumerHookName) { } else if c.FlowControl != nil { err := s.AddPostStartHook(priorityAndFairnessConfigConsumerHookName, func(context PostStartHookContext) error { <ins> go c.FlowControl.MaintainObservations(context.StopCh) </ins> go c.FlowControl.Run(context.StopCh) return nil })

}}) } <ins> // MaintainObservations keeps the observers from // metrics.PriorityLevelConcurrencyObserverPairGenerator from falling // too far behind func (cfgCtlr *configController) MaintainObservations(stopCh <-chan struct{}) { wait.Until(cfgCtlr.updateObservations, 10*time.Second, stopCh) } func (cfgCtlr *configController) updateObservations() { cfgCtlr.lock.Lock() defer cfgCtlr.lock.Unlock() for _, plc := range cfgCtlr.priorityLevelStates { if plc.queues != nil { plc.queues.UpdateObservations() } } } </ins> func (cfgCtlr *configController) Run(stopCh <-chan struct{}) error { defer cfgCtlr.configQueue.ShutDown() klog.Info("Starting API Priority and Fairness config controller")

type Interface interface { // Handle takes care of queuing and dispatching a request // characterized by the given digest.  The given `noteFn` will be <del> // invoked with the results of request classification.  If Handle // decides that the request should be executed then `execute()` // will be invoked once to execute the request; otherwise // `execute()` will not be invoked. </del> <ins> // invoked with the results of request classification.  If the // request is queued then `queueNoteFn` will be called twice, // first with `true` and then with `false`; otherwise // `queueNoteFn` will not be called at all.  If Handle decides // that the request should be executed then `execute()` will be // invoked once to execute the request; otherwise `execute()` will // not be invoked. </ins> Handle(ctx context.Context, requestDigest RequestDigest, noteFn func(fs *fctypesv1a1.FlowSchema, pl *fctypesv1a1.PriorityLevelConfiguration),

execFn func(), ) <ins> // MaintainObservations is a helper for maintaining statistics. MaintainObservations(stopCh <-chan struct{}) </ins> // Run monitors config objects from the main apiservers and causes // any needed changes to local behavior.  This method ceases // activity and returns after the given channel is closed.

return ctlrTestQueueSetCompleter{cqs.cts, cqs, qc}, nil } <ins> func (cqs *ctlrTestQueueSet) UpdateObservations() { } </ins> func (cqs *ctlrTestQueueSet) Dump(bool) debug.QueueSetDump { return debug.QueueSetDump{} }

// exactly once. StartRequest(ctx context.Context, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn QueueNoteFn) (req Request, idle bool) <ins> // UpdateObservations makes sure any time-based statistics have // caught up with the current clock reading UpdateObservations() </ins> // Dump saves and returns the instant internal state of the queue-set. // Note that dumping process will stop the queue-set from proceeding // any requests.

qs.counter.Add(-1) } <ins> func (qs *queueSet) UpdateObservations() { qs.obsPair.RequestsWaiting.Add(0) qs.obsPair.RequestsExecuting.Add(0) } </ins> func (qs *queueSet) Dump(includeRequestDetails bool) debug.QueueSetDump { qs.lock.Lock() defer qs.lock.Unlock()

return noRestraintRequest{}, false } <ins> func (noRestraint) UpdateObservations() { } </ins> func (noRestraint) Dump(bool) debug.QueueSetDump { return debug.QueueSetDump{} }