Skip to content

Commit f3c48db

Browse files
Endpoint for fetching tarballs
1 parent 0ce7fb7 commit f3c48db

File tree

6 files changed

+153
-3
lines changed

6 files changed

+153
-3
lines changed

database/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ impl Date {
6767
Date(Utc.ymd(year, month, day).and_hms(h, m, s))
6868
}
6969

70+
pub fn empty() -> Date {
71+
Date::ymd_hms(2000, 1, 1, 1, 1, 1)
72+
}
73+
7074
pub fn start_of_week(&self) -> Date {
7175
let weekday = self.0.weekday();
7276
// num_days_from_sunday is 0 for Sunday

database/src/pool.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ pub trait Connection: Send + Sync {
106106
///
107107
/// (Currently only works for try commits)
108108
async fn pr_of(&self, sha: &str) -> Option<u32>;
109+
110+
/// Returns the collection ids corresponding to the query. Usually just one.
111+
///
112+
/// Currently only supported by postgres (sqlite does not store self-profile
113+
/// results in the raw format).
114+
async fn list_self_profile(
115+
&self,
116+
aid: ArtifactId,
117+
crate_: &str,
118+
profile: &str,
119+
cache: &str,
120+
) -> Vec<(ArtifactIdNumber, i32)>;
109121
}
110122

111123
#[async_trait::async_trait]

database/src/pool/postgres.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ static MIGRATIONS: &[&str] = &[
179179
crate text not null references benchmark(name) on delete cascade on update cascade,
180180
profile text not null,
181181
cache text not null,
182-
prefix integer not null generated always as identity,
183182
PRIMARY KEY(aid, cid, crate, profile, cache)
184183
);
185184
"#,
@@ -1045,4 +1044,36 @@ where
10451044
&[&(artifact.0 as i16), &collection.0, &krate, &profile, &cache],
10461045
).await.unwrap();
10471046
}
1047+
async fn list_self_profile(
1048+
&self,
1049+
aid: ArtifactId,
1050+
crate_: &str,
1051+
profile: &str,
1052+
cache: &str,
1053+
) -> Vec<(ArtifactIdNumber, i32)> {
1054+
self.conn()
1055+
.query(
1056+
"
1057+
select aid, cid from raw_self_profile where
1058+
crate = $1
1059+
and profile = $2
1060+
and cache = $3
1061+
and aid = (select id from artifact where name = $4);
1062+
",
1063+
&[
1064+
&crate_,
1065+
&profile,
1066+
&cache,
1067+
&match aid {
1068+
ArtifactId::Commit(c) => c.sha,
1069+
ArtifactId::Artifact(a) => a,
1070+
},
1071+
],
1072+
)
1073+
.await
1074+
.unwrap()
1075+
.into_iter()
1076+
.map(|r| (ArtifactIdNumber(r.get::<_, i16>(0) as u32), r.get(1)))
1077+
.collect()
1078+
}
10481079
}

database/src/pool/sqlite.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,4 +853,13 @@ impl Connection for SqliteConnection {
853853
// yet clear.
854854
unimplemented!("recording raw self profile files is not implemented for sqlite")
855855
}
856+
async fn list_self_profile(
857+
&self,
858+
_aid: ArtifactId,
859+
_crate_: &str,
860+
_profile: &str,
861+
_cache: &str,
862+
) -> Vec<(ArtifactIdNumber, i32)> {
863+
Vec::new()
864+
}
856865
}

site/src/api.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,25 @@ pub mod status {
210210
}
211211
}
212212

213+
pub mod self_profile_raw {
214+
use serde::{Deserialize, Serialize};
215+
216+
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
217+
pub struct Request {
218+
pub commit: String,
219+
pub benchmark: String,
220+
pub run_name: String,
221+
pub cid: Option<i32>,
222+
}
223+
224+
#[derive(Debug, Clone, Serialize)]
225+
pub struct Response {
226+
pub cids: Vec<i32>,
227+
pub cid: i32,
228+
pub url: String,
229+
}
230+
}
231+
213232
pub mod self_profile {
214233
use database::QueryLabel;
215234
use serde::{Deserialize, Serialize};

site/src/server.rs

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ type Request = http::Request<hyper::Body>;
3737
type Response = http::Response<hyper::Body>;
3838

3939
pub use crate::api::{
40-
self, dashboard, data, days, github, graph, info, self_profile, status, CommitResponse,
41-
DateData, ServerResult, StyledBenchmarkName,
40+
self, dashboard, data, days, github, graph, info, self_profile, self_profile_raw, status,
41+
CommitResponse, DateData, ServerResult, StyledBenchmarkName,
4242
};
4343
use crate::db::{self, Cache, Crate, Profile};
4444
use crate::interpolate::Interpolated;
@@ -783,6 +783,77 @@ fn get_self_profile_data(
783783
Ok(profile)
784784
}
785785

786+
pub async fn handle_self_profile_raw(
787+
body: self_profile_raw::Request,
788+
data: &InputData,
789+
) -> ServerResult<self_profile_raw::Response> {
790+
log::info!("handle_self_profile_raw({:?})", body);
791+
let mut it = body.benchmark.rsplitn(2, '-');
792+
let bench_ty = it.next().ok_or(format!("no benchmark type"))?;
793+
let bench_name = it.next().ok_or(format!("no benchmark name"))?;
794+
795+
let cache = body
796+
.run_name
797+
.parse::<database::Cache>()
798+
.map_err(|e| format!("invalid run name: {:?}", e))?;
799+
800+
let conn = data.conn().await;
801+
802+
let aids_and_cids = conn
803+
.list_self_profile(
804+
ArtifactId::Commit(database::Commit {
805+
sha: body.commit,
806+
date: database::Date::empty(),
807+
}),
808+
bench_name,
809+
bench_ty,
810+
&body.run_name,
811+
)
812+
.await;
813+
let (aid, first_cid) = aids_and_cids
814+
.first()
815+
.copied()
816+
.ok_or_else(|| format!("No results for this commit"))?;
817+
818+
let cid = match body.cid {
819+
Some(cid) => {
820+
if aids_and_cids.iter().any(|(_, v)| *v == cid) {
821+
cid
822+
} else {
823+
return Err(format!("{} is not a collection ID at this artifact", cid));
824+
}
825+
}
826+
_ => first_cid,
827+
};
828+
829+
let url = format!(
830+
"https://perf-data.rust-lang.org/self-profile/{}/{}/{}/{}/self-profile-{}.tar.sz",
831+
aid.0,
832+
bench_name,
833+
bench_ty,
834+
cache.to_id(),
835+
cid
836+
);
837+
838+
let resp = reqwest::Client::new()
839+
.head(&url)
840+
.send()
841+
.await
842+
.map_err(|e| format!("fetching artifact: {:?}", e))?;
843+
if !resp.status().is_success() {
844+
return Err(format!(
845+
"Artifact did not resolve successfully: {:?} received",
846+
resp.status()
847+
));
848+
}
849+
850+
Ok(self_profile_raw::Response {
851+
cids: aids_and_cids.into_iter().map(|(_, cid)| cid).collect(),
852+
cid,
853+
url,
854+
})
855+
}
856+
786857
pub async fn handle_self_profile(
787858
body: self_profile::Request,
788859
data: &InputData,
@@ -1204,6 +1275,10 @@ async fn serve_req(ctx: Arc<Server>, req: Request) -> Result<Response, ServerErr
12041275
Ok(to_response(
12051276
handle_self_profile(body!(parse_body(&body)), &data).await,
12061277
))
1278+
} else if p == "/perf/self-profile-raw" {
1279+
Ok(to_response(
1280+
handle_self_profile_raw(body!(parse_body(&body)), &data).await,
1281+
))
12071282
} else {
12081283
return Ok(http::Response::builder()
12091284
.header_typed(ContentType::html())

0 commit comments

Comments
 (0)