Skip to content

Commit b80cbbe

Browse files
committed
update endpoints to return something more ui friendly
1 parent eb741c6 commit b80cbbe

File tree

3 files changed

+215
-16
lines changed

3 files changed

+215
-16
lines changed

database/src/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ const BENCHMARK_REQUEST_STATUS_IN_PROGRESS_STR: &str = "in_progress";
821821
const BENCHMARK_REQUEST_STATUS_COMPLETED_STR: &str = "completed";
822822

823823
impl BenchmarkRequestStatus {
824-
pub(crate) fn as_str(&self) -> &str {
824+
pub fn as_str(&self) -> &str {
825825
match self {
826826
Self::WaitingForArtifacts => BENCHMARK_REQUEST_STATUS_WAITING_FOR_ARTIFACTS_STR,
827827
Self::ArtifactsReady => BENCHMARK_REQUEST_STATUS_ARTIFACTS_READY_STR,
@@ -979,6 +979,10 @@ impl BenchmarkRequest {
979979
self.created_at
980980
}
981981

982+
pub fn commit_date(&self) -> Option<DateTime<Utc>> {
983+
self.commit_date
984+
}
985+
982986
pub fn is_master(&self) -> bool {
983987
matches!(self.commit_type, BenchmarkRequestType::Master { .. })
984988
}
@@ -1094,7 +1098,7 @@ impl fmt::Display for BenchmarkJobStatus {
10941098
}
10951099

10961100
#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
1097-
pub struct BenchmarkSet(u32);
1101+
pub struct BenchmarkSet(pub u32);
10981102

10991103
impl BenchmarkSet {
11001104
pub fn new(id: u32) -> Self {
@@ -1162,6 +1166,10 @@ impl BenchmarkJob {
11621166
pub fn status(&self) -> &BenchmarkJobStatus {
11631167
&self.status
11641168
}
1169+
1170+
pub fn created_at(&self) -> DateTime<Utc> {
1171+
self.created_at
1172+
}
11651173
}
11661174

11671175
/// Describes the final state of a job

site/src/api.rs

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -392,19 +392,88 @@ pub mod status {
392392
}
393393

394394
pub mod status_new {
395+
use chrono::{DateTime, Utc};
395396
use database::{BenchmarkJob, BenchmarkRequest, CollectorConfig};
396397
use serde::Serialize;
397398

399+
#[derive(Serialize, Debug)]
400+
#[serde(rename_all = "camelCase")]
401+
pub struct BenchmarkRequestStatusUi {
402+
pub state: String,
403+
pub completed_at: Option<DateTime<Utc>>,
404+
}
405+
406+
#[derive(Serialize, Debug)]
407+
#[serde(rename_all = "camelCase")]
408+
pub struct BenchmarkRequestTypeUi {
409+
pub r#type: String,
410+
pub tag: Option<String>,
411+
pub parent_sha: Option<String>,
412+
pub pr: Option<u32>,
413+
}
414+
415+
#[derive(Serialize, Debug)]
416+
#[serde(rename_all = "camelCase")]
417+
pub struct BenchmarkRequestUi {
418+
pub status: BenchmarkRequestStatusUi,
419+
pub request_type: BenchmarkRequestTypeUi,
420+
pub commit_date: Option<DateTime<Utc>>,
421+
pub created_at: DateTime<Utc>,
422+
pub backends: Vec<String>,
423+
pub profiles: String,
424+
pub errors: Vec<String>,
425+
}
426+
427+
#[derive(Serialize, Debug)]
428+
#[serde(rename_all = "camelCase")]
429+
pub struct BenchmarkJobStatusUi {
430+
pub state: String,
431+
pub started_at: Option<DateTime<Utc>>,
432+
pub completed_at: Option<DateTime<Utc>>,
433+
pub collector_name: Option<String>,
434+
}
435+
436+
#[derive(Serialize, Debug)]
437+
#[serde(rename_all = "camelCase")]
438+
pub struct BenchmarkJobUi {
439+
pub target: String,
440+
pub backend: String,
441+
pub profile: String,
442+
pub request_tag: String,
443+
pub benchmark_set: u32,
444+
pub created_at: DateTime<Utc>,
445+
pub status: BenchmarkJobStatusUi,
446+
pub deque_counter: u32,
447+
}
448+
449+
#[derive(Serialize, Debug)]
450+
#[serde(rename_all = "camelCase")]
451+
pub struct BenchmarkInProgressUi {
452+
pub request: BenchmarkRequestUi,
453+
pub jobs: Vec<BenchmarkJobUi>,
454+
}
455+
456+
#[derive(Serialize, Debug)]
457+
#[serde(rename_all = "camelCase")]
458+
pub struct CollectorConfigUi {
459+
pub name: String,
460+
pub target: String,
461+
pub benchmark_set: u32,
462+
pub is_active: bool,
463+
pub last_heartbeat_at: DateTime<Utc>,
464+
pub date_added: DateTime<Utc>,
465+
}
466+
398467
#[derive(Serialize, Debug)]
399468
pub struct Response {
400469
/// Completed requests alongside any errors
401-
pub completed: Vec<(BenchmarkRequest, Vec<String>)>,
470+
pub completed: Vec<BenchmarkRequestUi>,
402471
/// In progress requests alongside the jobs associated with the request
403-
pub in_progress: Vec<(BenchmarkRequest, Vec<BenchmarkJob>)>,
472+
pub in_progress: Vec<BenchmarkInProgressUi>,
404473
/// Configuration for all collectors including ones that are inactive
405-
pub collector_configs: Vec<CollectorConfig>,
474+
pub collector_configs: Vec<CollectorConfigUi>,
406475
/// The current queue
407-
pub queue: Vec<BenchmarkRequest>,
476+
pub queue: Vec<BenchmarkRequestUi>,
408477
}
409478
}
410479

Lines changed: 132 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,114 @@
11
use std::sync::Arc;
22

3+
use crate::api::status_new::{
4+
BenchmarkInProgressUi, BenchmarkJobStatusUi, BenchmarkJobUi, BenchmarkRequestStatusUi,
5+
BenchmarkRequestTypeUi, BenchmarkRequestUi, CollectorConfigUi,
6+
};
37
use crate::api::{status_new, ServerResult};
48
use crate::job_queue::build_queue;
59
use crate::load::SiteCtxt;
10+
use database::{
11+
BenchmarkJob, BenchmarkJobStatus, BenchmarkRequest, BenchmarkRequestStatus, CollectorConfig,
12+
};
13+
14+
fn benchmark_request_status_to_ui(status: BenchmarkRequestStatus) -> BenchmarkRequestStatusUi {
15+
BenchmarkRequestStatusUi {
16+
state: status.as_str().to_string(),
17+
completed_at: match status {
18+
BenchmarkRequestStatus::WaitingForArtifacts => None,
19+
BenchmarkRequestStatus::ArtifactsReady => None,
20+
BenchmarkRequestStatus::InProgress => None,
21+
BenchmarkRequestStatus::Completed { completed_at } => Some(completed_at),
22+
},
23+
}
24+
}
25+
26+
fn benchmark_request_type_to_ui(req: &BenchmarkRequest) -> BenchmarkRequestTypeUi {
27+
let request_type_str = if req.is_release() {
28+
"Release".to_string()
29+
} else if req.is_master() {
30+
"Master".to_string()
31+
} else {
32+
"Try".to_string()
33+
};
34+
35+
BenchmarkRequestTypeUi {
36+
r#type: request_type_str,
37+
tag: req.tag().map(|it| it.to_string()),
38+
parent_sha: req.parent_sha().map(|it| it.to_string()),
39+
pr: req.pr().map(|it| *it),
40+
}
41+
}
42+
43+
fn benchmark_request_to_ui(
44+
req: &BenchmarkRequest,
45+
errors: Vec<String>,
46+
) -> anyhow::Result<BenchmarkRequestUi> {
47+
Ok(BenchmarkRequestUi {
48+
status: benchmark_request_status_to_ui(req.status()),
49+
request_type: benchmark_request_type_to_ui(&req),
50+
commit_date: req.commit_date(),
51+
created_at: req.created_at(),
52+
backends: req.backends()?.iter().map(|it| it.to_string()).collect(),
53+
profiles: req.profiles()?.iter().map(|it| it.to_string()).collect(),
54+
errors,
55+
})
56+
}
57+
58+
fn benchmark_job_status_to_ui(status: &BenchmarkJobStatus) -> BenchmarkJobStatusUi {
59+
match status {
60+
BenchmarkJobStatus::Queued => BenchmarkJobStatusUi {
61+
state: status.as_str().to_string(),
62+
started_at: None,
63+
completed_at: None,
64+
collector_name: None,
65+
},
66+
BenchmarkJobStatus::InProgress {
67+
started_at,
68+
collector_name,
69+
} => BenchmarkJobStatusUi {
70+
state: status.as_str().to_string(),
71+
started_at: Some(*started_at),
72+
completed_at: None,
73+
collector_name: Some(collector_name.clone()),
74+
},
75+
BenchmarkJobStatus::Completed {
76+
started_at,
77+
completed_at,
78+
collector_name,
79+
success: _,
80+
} => BenchmarkJobStatusUi {
81+
state: status.as_str().to_string(),
82+
started_at: Some(*started_at),
83+
completed_at: Some(*completed_at),
84+
collector_name: Some(collector_name.clone()),
85+
},
86+
}
87+
}
88+
89+
fn benchmark_job_to_ui(job: &BenchmarkJob) -> BenchmarkJobUi {
90+
BenchmarkJobUi {
91+
target: job.target().as_str().to_string(),
92+
backend: job.backend().as_str().to_string(),
93+
profile: job.profile().as_str().to_string(),
94+
request_tag: job.request_tag().to_string(),
95+
benchmark_set: job.benchmark_set().0,
96+
created_at: job.created_at(),
97+
status: benchmark_job_status_to_ui(&job.status()),
98+
deque_counter: job.deque_count(),
99+
}
100+
}
101+
102+
fn collector_config_to_ui(config: &CollectorConfig) -> CollectorConfigUi {
103+
CollectorConfigUi {
104+
name: config.name().to_string(),
105+
target: config.target().as_str().to_string(),
106+
benchmark_set: config.benchmark_set().0,
107+
is_active: config.is_active(),
108+
last_heartbeat_at: config.last_heartbeat_at(),
109+
date_added: config.date_added(),
110+
}
111+
}
6112

7113
pub async fn handle_status_page_new(ctxt: Arc<SiteCtxt>) -> ServerResult<status_new::Response> {
8114
let conn = ctxt.conn().await;
@@ -12,11 +118,14 @@ pub async fn handle_status_page_new(ctxt: Arc<SiteCtxt>) -> ServerResult<status_
12118
let collector_configs = conn
13119
.get_collector_configs()
14120
.await
15-
.map_err(error_to_string)?;
121+
.map_err(error_to_string)?
122+
.iter()
123+
.map(collector_config_to_ui)
124+
.collect();
16125
// The query gives us `max_completed_requests` number of completed requests
17126
// and all inprogress requests without us needing to specify
18127
//
19-
// TODO; for `in_progress` requests we could look at the the completed
128+
// @TODO; for `in_progress` requests we could look at the the completed
20129
// `requests`, then use the `duration_ms` to display an estimated job
21130
// finish time. Could also do that on the frontend but probably makes
22131
// sense to do in SQL.
@@ -31,15 +140,28 @@ pub async fn handle_status_page_new(ctxt: Arc<SiteCtxt>) -> ServerResult<status_
31140
// @TODO; do we need both the queue and the inprogress jobs from the database?
32141
let queue = build_queue(&*conn, &index).await.map_err(error_to_string)?;
33142

143+
let mut completed: Vec<BenchmarkRequestUi> = vec![];
144+
for it in partial_data.completed_requests {
145+
completed.push(benchmark_request_to_ui(&it.0, it.2).map_err(error_to_string)?);
146+
}
147+
148+
let mut in_progress: Vec<BenchmarkInProgressUi> = vec![];
149+
for it in partial_data.in_progress {
150+
in_progress.push(BenchmarkInProgressUi {
151+
request: benchmark_request_to_ui(&it.0, vec![]).map_err(error_to_string)?,
152+
jobs: it.1.iter().map(benchmark_job_to_ui).collect(),
153+
});
154+
}
155+
156+
let mut queue_ui: Vec<BenchmarkRequestUi> = vec![];
157+
for it in queue {
158+
queue_ui.push(benchmark_request_to_ui(&it, vec![]).map_err(error_to_string)?);
159+
}
160+
34161
Ok(status_new::Response {
35-
completed: partial_data
36-
.completed_requests
37-
.iter()
38-
// @TODO Remove this
39-
.map(|it| (it.0.clone(), it.2.clone()))
40-
.collect(),
41-
in_progress: partial_data.in_progress,
162+
completed,
163+
in_progress,
42164
collector_configs,
43-
queue,
165+
queue: queue_ui,
44166
})
45167
}

0 commit comments

Comments
 (0)