@@ -17,6 +17,7 @@ limitations under the License.
1717package controller
1818
1919import (
20+ "context"
2021 "errors"
2122 "fmt"
2223 "sort"
@@ -36,8 +37,10 @@ import (
3637 cbclient "k8s.io/autoscaler/cluster-autoscaler/capacitybuffer/client"
3738 "k8s.io/autoscaler/cluster-autoscaler/capacitybuffer/fakepods"
3839 filters "k8s.io/autoscaler/cluster-autoscaler/capacitybuffer/filters"
40+ cbmetrics "k8s.io/autoscaler/cluster-autoscaler/capacitybuffer/metrics"
3941 translators "k8s.io/autoscaler/cluster-autoscaler/capacitybuffer/translators"
4042 updater "k8s.io/autoscaler/cluster-autoscaler/capacitybuffer/updater"
43+ "k8s.io/utils/clock"
4144)
4245
4346// BufferController performs updates on Buffers and convert them to pods to be injected
@@ -47,12 +50,14 @@ type BufferController interface {
4750}
4851
4952type bufferController struct {
50- client * cbclient.CapacityBufferClient
51- strategyFilter filters.Filter
52- translator translators.Translator
53- quotaAllocator * resourceQuotaAllocator
54- updater updater.StatusUpdater
55- queue workqueue.TypedRateLimitingInterface [string ]
53+ client * cbclient.CapacityBufferClient
54+ strategyFilter filters.Filter
55+ translator translators.Translator
56+ quotaAllocator * resourceQuotaAllocator
57+ updater updater.StatusUpdater
58+ queue workqueue.TypedRateLimitingInterface [string ]
59+ clock clock.Clock
60+ reconciliationTimeCache * cbmetrics.ReconciliationCache
5661}
5762
5863// NewBufferController creates new bufferController object
@@ -61,6 +66,8 @@ func NewBufferController(
6166 strategyFilter filters.Filter ,
6267 translator translators.Translator ,
6368 updater updater.StatusUpdater ,
69+ clock clock.Clock ,
70+ reconciliationTimeCache * cbmetrics.ReconciliationCache ,
6471) BufferController {
6572 bc := & bufferController {
6673 client : client ,
@@ -71,20 +78,42 @@ func NewBufferController(
7178 queue : workqueue .NewTypedRateLimitingQueueWithConfig (
7279 workqueue .DefaultTypedControllerRateLimiter [string ](), workqueue.TypedRateLimitingQueueConfig [string ]{Name : "CapacityBuffers" },
7380 ),
81+ clock : clock ,
82+ reconciliationTimeCache : reconciliationTimeCache ,
7483 }
7584 bc .configureEventHandlers ()
7685 return bc
7786}
7887
88+ // InitializeAndRunDefaultBufferController creates the default Capacity buffer controller and processing interval metric collector
89+ // and runs each of them asyncrounsly
90+ func InitializeAndRunDefaultBufferController (
91+ ctx context.Context ,
92+ client * cbclient.CapacityBufferClient ,
93+ resolver fakepods.Resolver ,
94+
95+ ) {
96+ realClock := clock.RealClock {}
97+ reconciledBuffersCache := cbmetrics .NewReconciliationCache ()
98+ // Accepting empty string as it represents nil value for ProvisioningStrategy
99+ defaultStrategies := []string {capacitybuffer .ActiveProvisioningStrategy , "" }
100+ controller := NewDefaultBufferController (client , resolver , defaultStrategies , reconciledBuffersCache , realClock )
101+ go controller .Run (ctx .Done ())
102+
103+ cbmetrics .RegisterReconciliationTimestampCollector (client , defaultStrategies , reconciledBuffersCache , realClock )
104+ }
105+
79106// NewDefaultBufferController creates bufferController with default configs
80107func NewDefaultBufferController (
81108 client * cbclient.CapacityBufferClient ,
82109 resolver fakepods.Resolver ,
110+ strategies []string ,
111+ reconciliationTimeCache * cbmetrics.ReconciliationCache ,
112+ clock clock.Clock ,
83113) BufferController {
84114 bc := & bufferController {
85- client : client ,
86- // Accepting empty string as it represents nil value for ProvisioningStrategy
87- strategyFilter : filters .NewStrategyFilter ([]string {capacitybuffer .ActiveProvisioningStrategy , "" }),
115+ client : client ,
116+ strategyFilter : filters .NewStrategyFilter (strategies ),
88117 translator : translators .NewCombinedTranslator (
89118 []translators.Translator {
90119 translators .NewPodTemplateBufferTranslator (client , resolver ),
@@ -96,6 +125,8 @@ func NewDefaultBufferController(
96125 queue : workqueue .NewTypedRateLimitingQueueWithConfig (
97126 workqueue .DefaultTypedControllerRateLimiter [string ](), workqueue.TypedRateLimitingQueueConfig [string ]{Name : "CapacityBuffers" },
98127 ),
128+ clock : clock ,
129+ reconciliationTimeCache : reconciliationTimeCache ,
99130 }
100131 bc .configureEventHandlers ()
101132 return bc
@@ -278,7 +309,10 @@ func (c *bufferController) reconcileNamespace(namespace string) error {
278309
279310 // Filter the desired provisioning strategy
280311 // Note: We process ALL buffers in the namespace that match the strategy.
281- filteredBuffers , _ := c .strategyFilter .Filter (buffers )
312+ filteredBuffers , filteredOutBuffers := c .strategyFilter .Filter (buffers )
313+
314+ // Update reconciliation time for filtered out buffers
315+ c .updateReconciliationTimeCache (filteredOutBuffers )
282316
283317 if len (filteredBuffers ) == 0 {
284318 return nil
@@ -306,7 +340,8 @@ func (c *bufferController) reconcileNamespace(namespace string) error {
306340 }
307341
308342 // Update buffer status by calling API server
309- updateErrors := c .updater .Update (filteredBuffers )
343+ updatedBuffers , updateErrors := c .updater .Update (filteredBuffers )
344+ c .updateReconciliationTimeCache (updatedBuffers )
310345 for _ , err := range updateErrors {
311346 runtime .HandleError (fmt .Errorf ("capacity buffer controller error: %w" , err ))
312347 }
@@ -318,3 +353,10 @@ func (c *bufferController) reconcileNamespace(namespace string) error {
318353
319354 return nil
320355}
356+
357+ func (c * bufferController ) updateReconciliationTimeCache (buffers []* v1.CapacityBuffer ) {
358+ if c .reconciliationTimeCache == nil || len (buffers ) == 0 {
359+ return
360+ }
361+ c .reconciliationTimeCache .Update (buffers , c .clock .Now ())
362+ }
0 commit comments