@@ -6,7 +6,10 @@ use crate::{cdn, db::Pool, target::TargetAtom, BuildQueue, Config};
66use anyhow:: Error ;
77use dashmap:: DashMap ;
88use prometheus:: proto:: MetricFamily ;
9- use std:: time:: { Duration , Instant } ;
9+ use std:: {
10+ collections:: HashSet ,
11+ time:: { Duration , Instant } ,
12+ } ;
1013
1114load_metric_type ! ( IntGauge as single) ;
1215load_metric_type ! ( IntCounter as single) ;
@@ -307,7 +310,26 @@ impl ServiceMetrics {
307310
308311 let queue_pending_count = queue. pending_count_by_priority ( ) ?;
309312
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+
311333 self . queued_crates_count_by_priority
312334 . with_label_values ( & [ & priority. to_string ( ) ] )
313335 . set ( * count as i64 ) ;
0 commit comments