Skip to content

Commit d034d9f

Browse files
authored
Merge pull request #1683 from Kobzol/estimation-pr-exact
Take in progress artifacts into account for perf. run estimation
2 parents a00f66f + 16e0e7d commit d034d9f

File tree

1 file changed

+53
-19
lines changed

1 file changed

+53
-19
lines changed

site/src/github.rs

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pub mod client;
22
pub mod comparison_summary;
33

44
use crate::api::github::Commit;
5-
use crate::load::{SiteCtxt, TryCommit};
5+
use crate::load::{MissingReason, SiteCtxt, TryCommit};
66
use std::time::Duration;
77

88
use serde::Deserialize;
@@ -21,6 +21,7 @@ pub const COMMENT_MARK_TEMPORARY: &str = "<!-- rust-timer: temporary -->";
2121
pub const COMMENT_MARK_ROLLUP: &str = "<!-- rust-timer: rollup -->";
2222

2323
pub use comparison_summary::post_finished;
24+
use database::Connection;
2425

2526
/// Enqueues try build artifacts and posts a message about them on the original rollup PR
2627
pub async fn unroll_rollup(
@@ -272,18 +273,8 @@ pub async fn enqueue_shas(
272273
msg.push('\n');
273274
}
274275

275-
let preceding_artifacts = count_preceding_in_queue(ctxt, &try_commit).await;
276-
let last_duration = conn
277-
.last_artifact_collection()
278-
.await
279-
.map(|collection| collection.duration)
280-
.unwrap_or(Duration::ZERO);
281-
282-
// "Guess" that the duration will take about an hour if we don't have data or it's
283-
// suspiciously fast.
284-
let last_duration = last_duration.max(Duration::from_secs(3600));
285-
// Also add the currently queued artifact to the duration
286-
let expected_duration = (last_duration.as_secs() * (preceding_artifacts + 1)) as f64;
276+
let (preceding_artifacts, expected_duration) =
277+
estimate_queue_info(ctxt, conn.as_ref(), &try_commit).await;
287278

288279
let verb = if preceding_artifacts == 1 {
289280
"is"
@@ -294,7 +285,7 @@ pub async fn enqueue_shas(
294285
let queue_msg = format!(
295286
r#"There {verb} currently {preceding_artifacts} other artifact{suffix} in the [queue](https://perf.rust-lang.org/status.html).
296287
It will probably take at least ~{:.1} hours until the benchmark run finishes."#,
297-
(expected_duration / 3600.0)
288+
(expected_duration.as_secs_f64() / 3600.0)
298289
);
299290

300291
msg.push_str(&format!(
@@ -314,13 +305,56 @@ It will probably take at least ~{:.1} hours until the benchmark run finishes."#,
314305
Ok(())
315306
}
316307

317-
/// Counts how many artifacts are in the queue before the specified commit.
318-
async fn count_preceding_in_queue(ctxt: &SiteCtxt, commit: &TryCommit) -> u64 {
308+
/// Counts how many artifacts are in the queue before the specified commit, and what is the expected
309+
/// duration until the specified commit will be finished.
310+
async fn estimate_queue_info(
311+
ctxt: &SiteCtxt,
312+
conn: &dyn Connection,
313+
commit: &TryCommit,
314+
) -> (u64, Duration) {
319315
let queue = ctxt.missing_commits().await;
320-
queue
316+
317+
// Queue without in-progress artifacts
318+
let queue_waiting: Vec<_> = queue
319+
.into_iter()
320+
.filter_map(|(c, reason)| match reason {
321+
MissingReason::InProgress(_) if c.sha != commit.sha => None,
322+
_ => Some(c),
323+
})
324+
.collect();
325+
326+
// Measure expected duration of waiting artifacts
327+
// How many commits are waiting (i.e. not running) in the queue before the specified commit?
328+
let preceding_waiting = queue_waiting
321329
.iter()
322-
.position(|(c, _)| c.sha == commit.sha())
323-
.unwrap_or(queue.len()) as u64
330+
.position(|c| c.sha == commit.sha())
331+
.unwrap_or(queue_waiting.len().saturating_sub(1)) as u64;
332+
333+
// Guess the expected full run duration of a waiting commit
334+
let last_duration = conn
335+
.last_artifact_collection()
336+
.await
337+
.map(|collection| collection.duration)
338+
.unwrap_or(Duration::ZERO);
339+
340+
// Guess that the duration will take about an hour if we don't have data or it's
341+
// suspiciously fast.
342+
let last_duration = last_duration.max(Duration::from_secs(3600));
343+
344+
let mut expected_duration = last_duration * (preceding_waiting + 1) as u32;
345+
let mut preceding = preceding_waiting;
346+
347+
// Add in-progress artifact duration and count (if any)
348+
if let Some(aid) = conn.in_progress_artifacts().await.pop() {
349+
preceding += 1;
350+
expected_duration += conn
351+
.in_progress_steps(&aid)
352+
.await
353+
.into_iter()
354+
.map(|s| s.expected.saturating_sub(s.duration))
355+
.sum();
356+
}
357+
(preceding, expected_duration)
324358
}
325359

326360
#[derive(Debug, Deserialize)]

0 commit comments

Comments
 (0)