Skip to content

Commit 43b9cfb

Browse files
Merge pull request #715 from Mark-Simulacrum/incremental-progress
Display progress of current benchmark
2 parents 2b833c7 + 6fd427b commit 43b9cfb

File tree

8 files changed

+185
-14
lines changed

8 files changed

+185
-14
lines changed

database/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,5 +674,14 @@ impl Index {
674674
}
675675
}
676676

677+
#[derive(Debug)]
678+
pub struct Step {
679+
pub name: String,
680+
pub is_done: bool,
681+
// The amount of time this step has been ongoing (or took, if completed).
682+
pub duration: Duration,
683+
pub expected: Duration,
684+
}
685+
677686
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
678687
pub struct CollectionId(i32);

database/src/pool.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{ArtifactId, ArtifactIdNumber};
2-
use crate::{Cache, CollectionId, Index, Profile, QueryDatum, QueuedCommit};
2+
use crate::{Cache, CollectionId, Index, Profile, QueryDatum, QueuedCommit, Step};
33
use hashbrown::HashMap;
44
use std::sync::{Arc, Mutex};
55
use std::time::Duration;
@@ -73,6 +73,8 @@ pub trait Connection: Send + Sync {
7373

7474
// Returns an artifact that is in progress.
7575
async fn in_progress_artifact(&self) -> Option<ArtifactId>;
76+
77+
async fn in_progress_steps(&self, aid: &ArtifactId) -> Vec<Step>;
7678
}
7779

7880
#[async_trait::async_trait]

database/src/pool/postgres.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ pub struct CachedStatements {
240240
get_error: Statement,
241241
collection_id: Statement,
242242
record_duration: Statement,
243+
in_progress_steps: Statement,
243244
}
244245

245246
pub struct PostgresTransaction<'a> {
@@ -361,6 +362,23 @@ impl PostgresConnection {
361362
duration
362363
) VALUES ($1, CURRENT_TIMESTAMP, $2)
363364
").await.unwrap(),
365+
in_progress_steps: conn.prepare("
366+
select step,
367+
end_time is not null,
368+
extract(epoch from interval '0 seconds'::interval +
369+
coalesce(end_time, statement_timestamp()) - start_time)::int4,
370+
extract(
371+
epoch from interval '0 seconds'::interval +
372+
(select end_time - start_time
373+
from collector_progress as cp
374+
where
375+
cp.step = collector_progress.step
376+
and cp.start_time is not null
377+
and cp.end_time is not null
378+
limit 1
379+
))::int4
380+
from collector_progress where aid = $1 order by step
381+
").await.unwrap(),
364382
}),
365383
conn,
366384
}
@@ -879,4 +897,23 @@ where
879897
}
880898
})
881899
}
900+
async fn in_progress_steps(&self, artifact: &ArtifactId) -> Vec<crate::Step> {
901+
let aid = self.artifact_id(artifact).await;
902+
903+
let steps = self
904+
.conn()
905+
.query(&self.statements().in_progress_steps, &[&(aid.0 as i16)])
906+
.await
907+
.unwrap();
908+
909+
steps
910+
.into_iter()
911+
.map(|row| crate::Step {
912+
name: row.get(0),
913+
is_done: row.get(1),
914+
duration: Duration::from_secs(row.get::<_, Option<i32>>(2).unwrap_or(0) as u64),
915+
expected: Duration::from_secs(row.get::<_, i32>(3) as u64),
916+
})
917+
.collect()
918+
}
882919
}

database/src/pool/sqlite.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,4 +716,38 @@ impl Connection for SqliteConnection {
716716
}
717717
})
718718
}
719+
async fn in_progress_steps(&self, artifact: &ArtifactId) -> Vec<crate::Step> {
720+
let aid = self.artifact_id(artifact).await;
721+
722+
self.raw_ref()
723+
.prepare(
724+
"
725+
select
726+
step,
727+
end_time is not null,
728+
coalesce(end, strftime('%s', 'now')) - start,
729+
(select end - start
730+
from collector_progress as cp
731+
where
732+
cp.step = collector_progress.step
733+
and cp.start is not null
734+
and cp.end is not null
735+
limit 1
736+
)
737+
from collector_progress where aid = ? order by step
738+
",
739+
)
740+
.unwrap()
741+
.query_map(params![&aid.0], |row| {
742+
Ok(crate::Step {
743+
name: row.get(0)?,
744+
is_done: row.get(1)?,
745+
duration: Duration::from_secs(row.get::<_, i64>(2)? as u64),
746+
expected: Duration::from_secs(row.get::<_, i64>(3)? as u64),
747+
})
748+
})
749+
.unwrap()
750+
.map(|r| r.unwrap())
751+
.collect()
752+
}
719753
}

site/src/api.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ pub mod days {
160160
}
161161

162162
pub mod status {
163-
use crate::load::{CurrentState, MissingReason};
163+
use crate::load::MissingReason;
164+
use database::ArtifactId;
164165
use database::Commit;
165166
use serde::{Deserialize, Serialize};
166167

@@ -171,7 +172,23 @@ pub mod status {
171172
pub error: Option<String>,
172173
}
173174

174-
#[derive(Debug, Clone, Serialize, Deserialize)]
175+
#[derive(Serialize, Debug)]
176+
pub struct Step {
177+
pub step: String,
178+
pub is_done: bool,
179+
// Seconds
180+
pub expected_duration: u64,
181+
// Seconds since start
182+
pub current_progress: u64,
183+
}
184+
185+
#[derive(Serialize, Debug)]
186+
pub struct CurrentState {
187+
pub artifact: ArtifactId,
188+
pub progress: Vec<Step>,
189+
}
190+
191+
#[derive(Serialize, Debug)]
175192
pub struct Response {
176193
pub last_commit: Commit,
177194
pub benchmarks: Vec<BenchmarkStatus>,

site/src/load.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,6 @@ pub enum MissingReason {
3737
InProgress,
3838
}
3939

40-
#[derive(Clone, Deserialize, Serialize, Debug)]
41-
pub struct CurrentState {
42-
pub commit: Commit,
43-
pub issue: Option<github::Issue>,
44-
pub benchmarks: Vec<Crate>,
45-
}
46-
4740
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq)]
4841
pub struct TryCommit {
4942
pub sha: String,

site/src/server.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,27 @@ pub async fn handle_status_page(data: Arc<InputData>) -> status::Response {
276276

277277
let missing = data.missing_commits().await;
278278
// FIXME: no current builds
279-
let current = None;
279+
let conn = data.conn().await;
280+
let current = if let Some(artifact) = conn.in_progress_artifact().await {
281+
let steps = conn
282+
.in_progress_steps(&artifact)
283+
.await
284+
.into_iter()
285+
.map(|s| crate::api::status::Step {
286+
step: s.name,
287+
is_done: s.is_done,
288+
expected_duration: s.expected.as_secs(),
289+
current_progress: s.duration.as_secs(),
290+
})
291+
.collect();
292+
293+
Some(crate::api::status::CurrentState {
294+
artifact,
295+
progress: steps,
296+
})
297+
} else {
298+
None
299+
};
280300

281301
status::Response {
282302
last_commit,

site/static/status.html

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,57 @@
5656
}
5757
let missing_div = document.querySelector("#missing-commits");
5858
if (data.current !== null) {
59+
let table = document.createElement("table");
60+
let tr = document.createElement("tr");
61+
let th = document.createElement("th");
62+
th.innerText = "Step";
63+
tr.appendChild(th);
64+
th = document.createElement("th");
65+
tr.appendChild(th);
66+
th = document.createElement("th");
67+
th.innerText = "Took";
68+
tr.appendChild(th);
69+
th = document.createElement("th");
70+
th.innerText = "Expected";
71+
tr.appendChild(th);
72+
table.appendChild(tr);
73+
74+
let left = 0;
75+
for (let step of data.current.progress) {
76+
let tr = document.createElement("tr");
77+
let td = document.createElement("td");
78+
td.innerText = step.step;
79+
tr.appendChild(td);
80+
td = document.createElement("td");
81+
let progress = document.createElement("progress");
82+
progress.setAttribute("max", step.expected_duration);
83+
progress.setAttribute("value", step.is_done ?
84+
step.expected_duration : step.current_progress);
85+
td.appendChild(progress);
86+
tr.appendChild(td);
87+
td = document.createElement("td");
88+
td.innerHTML = step.current_progress == 0 ? "" :
89+
format_duration(step.current_progress);
90+
tr.appendChild(td);
91+
td = document.createElement("td");
92+
td.innerHTML = format_duration(step.expected_duration);
93+
tr.appendChild(td);
94+
if (!step.is_done) {
95+
left += step.expected_duration - step.current_progress;
96+
}
97+
table.appendChild(tr);
98+
}
5999
let element = document.createElement("p");
60-
element.innerHTML = `Currently benchmarking:
61-
${commit_url(data.current.commit)}<br>${data.current.benchmarks.length} benchmarks \
62-
left out of ${data.benchmarks.length} total: ${data.current.benchmarks.join(", ")}.`;
100+
let artifact_desc = "";
101+
if (data.current.artifact.Commit) {
102+
artifact_desc = commit_url(data.current.artifact.Commit);
103+
} else {
104+
artifact_desc = data.current.Artifact;
105+
}
106+
element.innerHTML = `Currently benchmarking: ${artifact_desc}.
107+
<br>Time left: ${format_duration(left)}`;
63108
missing_div.appendChild(element);
109+
missing_div.appendChild(table);
64110
} else {
65111
let element = document.createElement("p");
66112
element.innerHTML = `(Current work is not currently displayed; this is being worked on)`;
@@ -109,6 +155,19 @@
109155
return `<a href="https://github.com/rust-lang/rust/commit/${commit.sha}">${commit.sha.substr(0, 13)}</a>`;
110156
}
111157

158+
function format_duration(seconds) {
159+
let secs = seconds % 60;
160+
let mins = Math.trunc(seconds / 60);
161+
let hours = Math.trunc(mins / 60);
162+
mins -= hours*60;
163+
164+
let s = `${mins < 10 ? "&nbsp;" + mins : mins}m${secs < 10 ? "0" + secs : secs}s`;
165+
if (hours > 0) {
166+
s = `${hours}h ${s}`;
167+
}
168+
return s;
169+
}
170+
112171
function addHours(date, hours) {
113172
let ret = new Date(date);
114173
ret.setTime(ret.getTime() + (hours*60*60*1000));

0 commit comments

Comments
 (0)