@@ -71,6 +71,10 @@ type Collector interface {
7171 // Watch registers a singleton function to call when a specific collector's status changes.
7272 // The passed name is the namespace/name of the metric owned by the respective collector.
7373 Watch (func (types.NamespacedName ))
74+ // Pause metric collection
75+ Pause (metric * autoscalingv1alpha1.Metric )
76+ // Resume metric collection
77+ Resume (metric * autoscalingv1alpha1.Metric )
7478}
7579
7680// MetricClient surfaces the metrics that can be obtained via the collector.
@@ -82,12 +86,6 @@ type MetricClient interface {
8286 // StableAndPanicRPS returns both the stable and the panic RPS
8387 // for the given replica as of the given time.
8488 StableAndPanicRPS (key types.NamespacedName , now time.Time ) (float64 , float64 , error )
85-
86- // Pause metric collection
87- Pause (key types.NamespacedName )
88-
89- // Resume metric collection
90- Resume (key types.NamespacedName )
9189}
9290
9391// MetricCollector manages collection of metrics for many entities.
@@ -172,7 +170,9 @@ func (c *MetricCollector) Record(key types.NamespacedName, now time.Time, stat S
172170 }
173171}
174172
175- func (c * MetricCollector ) Pause (key types.NamespacedName ) {
173+ func (c * MetricCollector ) Pause (metric * autoscalingv1alpha1.Metric ) {
174+ key := types.NamespacedName {Namespace : metric .Namespace , Name : metric .Name }
175+
176176 c .collectionsMutex .RLock ()
177177 defer c .collectionsMutex .RUnlock ()
178178
@@ -181,7 +181,9 @@ func (c *MetricCollector) Pause(key types.NamespacedName) {
181181 }
182182}
183183
184- func (c * MetricCollector ) Resume (key types.NamespacedName ) {
184+ func (c * MetricCollector ) Resume (metric * autoscalingv1alpha1.Metric ) {
185+ key := types.NamespacedName {Namespace : metric .Namespace , Name : metric .Name }
186+
185187 c .collectionsMutex .RLock ()
186188 defer c .collectionsMutex .RUnlock ()
187189
@@ -272,11 +274,12 @@ type (
272274 rpsPanicBuckets windowAverager
273275
274276 // Fields relevant for metric scraping specifically.
275- scraper StatsScraper
276- lastErr error
277- grp sync.WaitGroup
278- paused bool
279- stopCh chan struct {}
277+ creationTime time.Time
278+ scraper StatsScraper
279+ lastErr error
280+ grp sync.WaitGroup
281+ paused bool
282+ stopCh chan struct {}
280283 }
281284)
282285
@@ -309,6 +312,7 @@ func newCollection(metric *autoscalingv1alpha1.Metric, scraper StatsScraper, clo
309312 }
310313 }
311314
315+ creationTime := time .Now ()
312316 c := & collection {
313317 metric : metric ,
314318 concurrencyBuckets : bucketCtor (
@@ -321,8 +325,9 @@ func newCollection(metric *autoscalingv1alpha1.Metric, scraper StatsScraper, clo
321325 metric .Spec .PanicWindow , config .BucketSize ),
322326 scraper : scraper ,
323327
324- stopCh : make (chan struct {}),
325- paused : false ,
328+ stopCh : make (chan struct {}),
329+ creationTime : creationTime ,
330+ paused : false ,
326331 }
327332
328333 key := types.NamespacedName {Namespace : metric .Namespace , Name : metric .Name }
@@ -339,7 +344,11 @@ func newCollection(metric *autoscalingv1alpha1.Metric, scraper StatsScraper, clo
339344 case <- c .stopCh :
340345 return
341346 case <- scrapeTicker .C ():
342- if c .getPaused () {
347+ now := time .Now ()
348+ timeSinceCreation := now .Sub (c .creationTime )
349+ stableWindow := 2 * c .metric .Spec .StableWindow
350+ // initially wait two stable windows to allow initial scale to zero due to activator behavior
351+ if timeSinceCreation > 2 * stableWindow && c .getPaused () {
343352 continue
344353 }
345354 scraper := c .getScraper ()
0 commit comments