Skip to content

Commit 068fd19

Browse files
committed
Add endpoint for single graph
1 parent 64c192d commit 068fd19

File tree

5 files changed

+92
-22
lines changed

5 files changed

+92
-22
lines changed

site/src/api.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,28 @@ pub mod dashboard {
4242
}
4343

4444
pub mod graph {
45+
use super::graphs::{GraphKind, Series};
46+
use collector::Bound;
47+
use serde::{Deserialize, Serialize};
48+
49+
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
50+
pub struct Request {
51+
pub benchmark: String,
52+
pub profile: String,
53+
pub scenario: String,
54+
pub metric: String,
55+
pub start: Bound,
56+
pub end: Bound,
57+
pub kind: GraphKind,
58+
}
59+
60+
#[derive(Debug, PartialEq, Clone, Serialize)]
61+
pub struct Response {
62+
pub series: Series,
63+
}
64+
}
65+
66+
pub mod graphs {
4567
use collector::Bound;
4668
use serde::{Deserialize, Serialize};
4769
use std::collections::{HashMap, HashSet};

site/src/load.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub struct SiteCtxt {
7979
/// Site configuration
8080
pub config: Config,
8181
/// Cached site landing page
82-
pub landing_page: ArcSwap<Option<Arc<crate::api::graph::Response>>>,
82+
pub landing_page: ArcSwap<Option<Arc<crate::api::graphs::Response>>>,
8383
/// Index of various common queries
8484
pub index: ArcSwap<crate::db::Index>,
8585
/// Database connection pool

site/src/request_handlers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ mod status_page;
99
pub use bootstrap::handle_bootstrap;
1010
pub use dashboard::handle_dashboard;
1111
pub use github::handle_github;
12-
pub use graph::handle_graphs;
12+
pub use graph::{handle_graph, handle_graphs};
1313
pub use next_commit::handle_next_commit;
1414
pub use self_profile::{
1515
handle_self_profile, handle_self_profile_processed_download, handle_self_profile_raw,

site/src/request_handlers/graph.rs

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,31 @@ use collector::Bound;
22
use std::collections::HashMap;
33
use std::sync::Arc;
44

5-
use crate::api::graph::GraphKind;
6-
use crate::api::{graph, ServerResult};
5+
use crate::api::graphs::GraphKind;
6+
use crate::api::{graph, graphs, ServerResult};
77
use crate::db::{self, ArtifactId, Benchmark, Profile, Scenario};
88
use crate::interpolate::IsInterpolated;
99
use crate::load::SiteCtxt;
1010
use crate::selector::{Query, Selector, SeriesResponse, Tag};
1111

12+
pub async fn handle_graph(body: graph::Request, ctxt: &SiteCtxt) -> ServerResult<graph::Response> {
13+
log::info!("handle_graph({:?})", body);
14+
15+
create_graph(body, ctxt).await
16+
}
17+
1218
pub async fn handle_graphs(
13-
body: graph::Request,
19+
body: graphs::Request,
1420
ctxt: &SiteCtxt,
15-
) -> ServerResult<Arc<graph::Response>> {
16-
log::info!("handle_graph({:?})", body);
21+
) -> ServerResult<Arc<graphs::Response>> {
22+
log::info!("handle_graphs({:?})", body);
1723

1824
let is_default_query = body
19-
== graph::Request {
25+
== graphs::Request {
2026
start: Bound::None,
2127
end: Bound::None,
2228
stat: String::from("instructions:u"),
23-
kind: graph::GraphKind::Raw,
29+
kind: graphs::GraphKind::Raw,
2430
};
2531

2632
if is_default_query {
@@ -30,21 +36,41 @@ pub async fn handle_graphs(
3036
}
3137
}
3238

33-
let resp = graph_response(body, ctxt).await?;
39+
let resp = create_graphs(body, ctxt).await?;
3440

3541
if is_default_query {
3642
ctxt.landing_page.store(Arc::new(Some(resp.clone())));
3743
}
3844

3945
Ok(resp)
4046
}
47+
async fn create_graph(body: graph::Request, ctxt: &SiteCtxt) -> ServerResult<graph::Response> {
48+
let artifact_ids = artifact_ids_for_range(ctxt, body.start, body.end);
49+
let mut series_iterator = ctxt
50+
.statistic_series(
51+
Query::new()
52+
.set::<String>(Tag::Benchmark, Selector::One(body.benchmark))
53+
.set::<String>(Tag::Profile, Selector::One(body.profile))
54+
.set::<String>(Tag::Scenario, Selector::One(body.scenario))
55+
.set::<String>(Tag::Metric, Selector::One(body.metric)),
56+
Arc::new(artifact_ids),
57+
)
58+
.await?
59+
.into_iter()
60+
.map(SeriesResponse::interpolate);
61+
62+
let result = series_iterator.next().unwrap();
63+
let graph_series = graph_series(result.series, body.kind);
64+
Ok(graph::Response {
65+
series: graph_series,
66+
})
67+
}
4168

42-
async fn graph_response(
43-
body: graph::Request,
69+
async fn create_graphs(
70+
body: graphs::Request,
4471
ctxt: &SiteCtxt,
45-
) -> ServerResult<Arc<graph::Response>> {
46-
let range = ctxt.data_range(body.start..=body.end);
47-
let commits: Arc<Vec<_>> = Arc::new(range.into_iter().map(|c| c.into()).collect());
72+
) -> ServerResult<Arc<graphs::Response>> {
73+
let artifact_ids = Arc::new(artifact_ids_for_range(ctxt, body.start, body.end));
4874
let mut benchmarks = HashMap::new();
4975

5076
let interpolated_responses: Vec<_> = ctxt
@@ -54,7 +80,7 @@ async fn graph_response(
5480
.set::<String>(Tag::Profile, Selector::All)
5581
.set::<String>(Tag::Scenario, Selector::All)
5682
.set::<String>(Tag::Metric, Selector::One(body.stat)),
57-
commits.clone(),
83+
artifact_ids.clone(),
5884
)
5985
.await?
6086
.into_iter()
@@ -79,8 +105,8 @@ async fn graph_response(
79105
.insert(scenario, graph_series);
80106
}
81107

82-
Ok(Arc::new(graph::Response {
83-
commits: Arc::try_unwrap(commits)
108+
Ok(Arc::new(graphs::Response {
109+
commits: Arc::try_unwrap(artifact_ids)
84110
.unwrap()
85111
.into_iter()
86112
.map(|c| match c {
@@ -92,13 +118,18 @@ async fn graph_response(
92118
}))
93119
}
94120

121+
fn artifact_ids_for_range(ctxt: &SiteCtxt, start: Bound, end: Bound) -> Vec<ArtifactId> {
122+
let range = ctxt.data_range(start..=end);
123+
range.into_iter().map(|c| c.into()).collect()
124+
}
125+
95126
/// Creates a summary "benchmark" that averages the results of all other
96127
/// test cases per profile type
97128
fn create_summary(
98129
ctxt: &SiteCtxt,
99130
interpolated_responses: &[SeriesResponse<Vec<((ArtifactId, Option<f64>), IsInterpolated)>>],
100131
graph_kind: GraphKind,
101-
) -> ServerResult<HashMap<Profile, HashMap<String, graph::Series>>> {
132+
) -> ServerResult<HashMap<Profile, HashMap<String, graphs::Series>>> {
102133
let mut baselines = HashMap::new();
103134
let mut summary_benchmark = HashMap::new();
104135
let summary_query_cases = iproduct!(
@@ -152,8 +183,8 @@ fn create_summary(
152183
fn graph_series(
153184
points: impl Iterator<Item = ((ArtifactId, Option<f64>), IsInterpolated)>,
154185
kind: GraphKind,
155-
) -> graph::Series {
156-
let mut graph_series = graph::Series {
186+
) -> graphs::Series {
187+
let mut graph_series = graphs::Series {
157188
points: Vec::new(),
158189
interpolated_indices: Default::default(),
159190
};

site/src/server.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use serde::de::DeserializeOwned;
1818
use serde::Serialize;
1919

2020
pub use crate::api::{
21-
self, bootstrap, comparison, dashboard, github, graph, info, self_profile, self_profile_raw,
21+
self, bootstrap, comparison, dashboard, github, graphs, info, self_profile, self_profile_raw,
2222
status, triage, ServerResult,
2323
};
2424
use crate::db::{self, ArtifactId};
@@ -403,6 +403,23 @@ async fn serve_req(server: Server, req: Request) -> Result<Response, ServerError
403403
"/perf/self-profile-raw" => Ok(to_response(
404404
request_handlers::handle_self_profile_raw(check!(parse_body(&body)), &ctxt).await,
405405
)),
406+
"/perf/graph" => Ok(
407+
match request_handlers::handle_graph(check!(parse_body(&body)), &ctxt).await {
408+
Ok(result) => {
409+
let response = http::Response::builder()
410+
.header_typed(ContentType::json())
411+
.header_typed(CacheControl::new().with_no_cache().with_no_store());
412+
let body = serde_json::to_vec(&result).unwrap();
413+
response.body(hyper::Body::from(body)).unwrap()
414+
}
415+
Err(err) => http::Response::builder()
416+
.status(StatusCode::INTERNAL_SERVER_ERROR)
417+
.header_typed(ContentType::text_utf8())
418+
.header_typed(CacheControl::new().with_no_cache().with_no_store())
419+
.body(hyper::Body::from(err))
420+
.unwrap(),
421+
},
422+
),
406423
"/perf/graphs" => Ok(
407424
match request_handlers::handle_graphs(check!(parse_body(&body)), &ctxt).await {
408425
Ok(result) => {

0 commit comments

Comments
 (0)