@@ -6,7 +6,10 @@ use crate::{cdn, db::Pool, target::TargetAtom, BuildQueue, Config};
6
6
use anyhow:: Error ;
7
7
use dashmap:: DashMap ;
8
8
use prometheus:: proto:: MetricFamily ;
9
- use std:: time:: { Duration , Instant } ;
9
+ use std:: {
10
+ collections:: HashSet ,
11
+ time:: { Duration , Instant } ,
12
+ } ;
10
13
11
14
load_metric_type ! ( IntGauge as single) ;
12
15
load_metric_type ! ( IntCounter as single) ;
@@ -307,7 +310,26 @@ impl ServiceMetrics {
307
310
308
311
let queue_pending_count = queue. pending_count_by_priority ( ) ?;
309
312
310
- for ( priority, count) in queue_pending_count. iter ( ) {
313
+ // gauges keep their old value per label when it's not removed, reset to zero or updated.
314
+ // When a priority is used at least once, it would be kept in the metric and the last
315
+ // value would be remembered. `pending_count_by_priority` returns only the priorities
316
+ // that are currently in the queue, which means when the tasks for a priority are
317
+ // finished, we wouldn't update the metric any more, which means a wrong value is
318
+ // in the metric.
319
+ //
320
+ // The solution is to reset the metric, and then set all priorities again.
321
+ self . queued_crates_count_by_priority . reset ( ) ;
322
+
323
+ // for commonly used priorities we want the value to be zero, and not missing,
324
+ // when there are no items in the queue with that priority.
325
+ // So we create a set of all priorities we want to be explicitly zeroed, combined
326
+ // with the actual priorities in the queue.
327
+ let all_priorities: HashSet < i32 > =
328
+ queue_pending_count. keys ( ) . copied ( ) . chain ( 0 ..=20 ) . collect ( ) ;
329
+
330
+ for priority in all_priorities {
331
+ let count = queue_pending_count. get ( & priority) . unwrap_or ( & 0 ) ;
332
+
311
333
self . queued_crates_count_by_priority
312
334
. with_label_values ( & [ & priority. to_string ( ) ] )
313
335
. set ( * count as i64 ) ;
0 commit comments