Skip to content

Commit 8d404d4

Browse files
committed
Make it impossible to not assign completed date for completed benchmark requests
Also create benchmark requests with a struct literal in the Postgres code, to make it impossible to forget setting some fields.
1 parent 723deb5 commit 8d404d4

File tree

4 files changed

+93
-102
lines changed

4 files changed

+93
-102
lines changed

database/src/lib.rs

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ impl Scenario {
309309
}
310310
}
311311

312+
use anyhow::anyhow;
312313
use std::cmp::Ordering;
313314
use std::str::FromStr;
314315

@@ -802,7 +803,7 @@ pub enum BenchmarkRequestStatus {
802803
WaitingForArtifacts,
803804
ArtifactsReady,
804805
InProgress,
805-
Completed,
806+
Completed { completed_at: DateTime<Utc> },
806807
}
807808

808809
const WAITING_FOR_ARTIFACTS_STR: &str = "waiting_for_artifacts";
@@ -811,44 +812,48 @@ const IN_PROGRESS_STR: &str = "in_progress";
811812
const COMPLETED_STR: &str = "completed";
812813

813814
impl BenchmarkRequestStatus {
814-
pub fn as_str(&self) -> &str {
815+
pub(crate) fn as_str(&self) -> &str {
815816
match self {
816-
BenchmarkRequestStatus::WaitingForArtifacts => WAITING_FOR_ARTIFACTS_STR,
817-
BenchmarkRequestStatus::ArtifactsReady => ARTIFACTS_READY_STR,
818-
BenchmarkRequestStatus::InProgress => IN_PROGRESS_STR,
819-
BenchmarkRequestStatus::Completed { .. } => COMPLETED_STR,
817+
Self::WaitingForArtifacts => WAITING_FOR_ARTIFACTS_STR,
818+
Self::ArtifactsReady => ARTIFACTS_READY_STR,
819+
Self::InProgress => IN_PROGRESS_STR,
820+
Self::Completed { .. } => COMPLETED_STR,
820821
}
821822
}
822-
}
823-
824-
impl fmt::Display for BenchmarkRequestStatus {
825-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
826-
f.write_str(self.as_str())
827-
}
828-
}
829-
830-
impl<'a> tokio_postgres::types::FromSql<'a> for BenchmarkRequestStatus {
831-
fn from_sql(
832-
ty: &tokio_postgres::types::Type,
833-
raw: &'a [u8],
834-
) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
835-
// Decode raw bytes into &str with Postgres' own text codec
836-
let s: &str = <&str as tokio_postgres::types::FromSql>::from_sql(ty, raw)?;
837823

838-
match s {
824+
pub(crate) fn from_str_and_completion_date(
825+
text: &str,
826+
completion_date: Option<DateTime<Utc>>,
827+
) -> anyhow::Result<Self> {
828+
match text {
839829
WAITING_FOR_ARTIFACTS_STR => Ok(Self::WaitingForArtifacts),
840830
ARTIFACTS_READY_STR => Ok(Self::ArtifactsReady),
841831
IN_PROGRESS_STR => Ok(Self::InProgress),
842-
COMPLETED_STR => Ok(Self::Completed),
843-
other => Err(format!("unknown benchmark_request_status '{other}'").into()),
832+
COMPLETED_STR => Ok(Self::Completed {
833+
completed_at: completion_date.ok_or_else(|| {
834+
anyhow!("No completion date for a completed BenchmarkRequestStatus")
835+
})?,
836+
}),
837+
_ => Err(anyhow!("Unknown BenchmarkRequestStatus `{text}`")),
844838
}
845839
}
846840

847-
fn accepts(ty: &tokio_postgres::types::Type) -> bool {
848-
<&str as tokio_postgres::types::FromSql>::accepts(ty)
841+
pub(crate) fn completed_at(&self) -> Option<DateTime<Utc>> {
842+
match self {
843+
Self::Completed { completed_at } => Some(*completed_at),
844+
_ => None,
845+
}
849846
}
850847
}
851848

849+
impl fmt::Display for BenchmarkRequestStatus {
850+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
851+
f.write_str(self.as_str())
852+
}
853+
}
854+
855+
856+
852857
const BENCHMARK_REQUEST_TRY_STR: &str = "try";
853858
const BENCHMARK_REQUEST_MASTER_STR: &str = "master";
854859
const BENCHMARK_REQUEST_RELEASE_STR: &str = "release";
@@ -885,7 +890,6 @@ impl fmt::Display for BenchmarkRequestType {
885890
pub struct BenchmarkRequest {
886891
pub commit_type: BenchmarkRequestType,
887892
pub created_at: DateTime<Utc>,
888-
pub completed_at: Option<DateTime<Utc>>,
889893
pub status: BenchmarkRequestStatus,
890894
pub backends: String,
891895
pub profiles: String,
@@ -896,18 +900,15 @@ impl BenchmarkRequest {
896900
tag: &str,
897901
created_at: DateTime<Utc>,
898902
status: BenchmarkRequestStatus,
899-
backends: &str,
900-
profiles: &str,
901903
) -> Self {
902904
Self {
903905
commit_type: BenchmarkRequestType::Release {
904906
tag: tag.to_string(),
905907
},
906908
created_at,
907-
completed_at: None,
908909
status,
909-
backends: backends.to_string(),
910-
profiles: profiles.to_string(),
910+
backends: String::new(),
911+
profiles: String::new(),
911912
}
912913
}
913914

@@ -927,7 +928,6 @@ impl BenchmarkRequest {
927928
parent_sha: parent_sha.map(|it| it.to_string()),
928929
},
929930
created_at,
930-
completed_at: None,
931931
status,
932932
backends: backends.to_string(),
933933
profiles: profiles.to_string(),
@@ -950,7 +950,6 @@ impl BenchmarkRequest {
950950
parent_sha: parent_sha.to_string(),
951951
},
952952
created_at,
953-
completed_at: None,
954953
status,
955954
backends: backends.to_string(),
956955
profiles: profiles.to_string(),

database/src/pool.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,6 @@ mod tests {
434434
"1.8.0",
435435
time,
436436
BenchmarkRequestStatus::ArtifactsReady,
437-
"cranelift,llvm",
438-
"",
439437
);
440438

441439
let db = db.connection().await;
@@ -490,8 +488,6 @@ mod tests {
490488
"1.8.0",
491489
time,
492490
BenchmarkRequestStatus::ArtifactsReady,
493-
"cranelift,llvm",
494-
"",
495491
);
496492

497493
let db = db.connection().await;

database/src/pool/postgres.rs

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,58 +1453,56 @@ where
14531453
let benchmark_requests = rows
14541454
.iter()
14551455
.map(|row| {
1456-
let tag = row.get::<_, Option<&str>>(0);
1457-
let parent_sha = row.get::<_, Option<&str>>(1);
1456+
let tag = row.get::<_, Option<String>>(0);
1457+
let parent_sha = row.get::<_, Option<String>>(1);
14581458
let pr = row.get::<_, Option<i32>>(2);
14591459
let commit_type = row.get::<_, &str>(3);
1460-
let status = row.get::<_, BenchmarkRequestStatus>(4);
1460+
let status = row.get::<_, &str>(4);
14611461
let created_at = row.get::<_, DateTime<Utc>>(5);
14621462
let completed_at = row.get::<_, Option<DateTime<Utc>>>(6);
1463-
let backends = row.get::<_, &str>(7);
1464-
let profiles = row.get::<_, &str>(8);
1463+
let backends = row.get::<_, String>(7);
1464+
let profiles = row.get::<_, String>(8);
1465+
1466+
let pr = pr.map(|v| v as u32);
1467+
1468+
let status =
1469+
BenchmarkRequestStatus::from_str_and_completion_date(status, completed_at)
1470+
.expect("Invalid BenchmarkRequestStatus data in the database");
14651471

14661472
match commit_type {
1467-
BENCHMARK_REQUEST_TRY_STR => {
1468-
let mut try_benchmark = BenchmarkRequest::create_try(
1469-
tag,
1473+
BENCHMARK_REQUEST_TRY_STR => BenchmarkRequest {
1474+
commit_type: BenchmarkRequestType::Try {
1475+
sha: tag,
14701476
parent_sha,
1471-
pr.unwrap() as u32,
1472-
created_at,
1473-
status,
1474-
backends,
1475-
profiles,
1476-
);
1477-
try_benchmark.completed_at = completed_at;
1478-
try_benchmark
1479-
}
1480-
BENCHMARK_REQUEST_MASTER_STR => {
1481-
let mut master_benchmark = BenchmarkRequest::create_master(
1482-
tag.expect("Master commit in DB without SHA"),
1483-
parent_sha.unwrap(),
1484-
pr.unwrap() as u32,
1485-
created_at,
1486-
status,
1487-
backends,
1488-
profiles,
1489-
);
1490-
master_benchmark.completed_at = completed_at;
1491-
master_benchmark
1492-
}
1493-
BENCHMARK_REQUEST_RELEASE_STR => {
1494-
let mut release_benchmark = BenchmarkRequest::create_release(
1495-
tag.expect("Release commit in DB witohut SHA"),
1496-
created_at,
1497-
status,
1498-
backends,
1499-
profiles,
1500-
);
1501-
release_benchmark.completed_at = completed_at;
1502-
release_benchmark
1503-
}
1504-
_ => panic!(
1505-
"Invalid `commit_type` for `BenchmarkRequest` {}",
1506-
commit_type
1507-
),
1477+
pr: pr.expect("Try commit in the DB without a PR"),
1478+
},
1479+
created_at,
1480+
status,
1481+
backends,
1482+
profiles,
1483+
},
1484+
BENCHMARK_REQUEST_MASTER_STR => BenchmarkRequest {
1485+
commit_type: BenchmarkRequestType::Master {
1486+
sha: tag.expect("Master commit in the DB without a SHA"),
1487+
parent_sha: parent_sha
1488+
.expect("Master commit in the DB without a parent SHA"),
1489+
pr: pr.expect("Master commit in the DB without a PR"),
1490+
},
1491+
created_at,
1492+
status,
1493+
backends,
1494+
profiles,
1495+
},
1496+
BENCHMARK_REQUEST_RELEASE_STR => BenchmarkRequest {
1497+
commit_type: BenchmarkRequestType::Release {
1498+
tag: tag.expect("Release commit in the DB without a SHA"),
1499+
},
1500+
created_at,
1501+
status,
1502+
backends,
1503+
profiles,
1504+
},
1505+
_ => panic!("Invalid `commit_type` for `BenchmarkRequest` {commit_type}",),
15081506
}
15091507
})
15101508
.collect();
@@ -1513,23 +1511,25 @@ where
15131511

15141512
async fn update_benchmark_request_status(
15151513
&mut self,
1516-
benchmark_request: &BenchmarkRequest,
1517-
benchmark_request_status: BenchmarkRequestStatus,
1514+
request: &BenchmarkRequest,
1515+
status: BenchmarkRequestStatus,
15181516
) -> anyhow::Result<()> {
1519-
let tx = self
1520-
.conn_mut()
1521-
.transaction()
1522-
.await
1523-
.context("failed to start transaction")?;
1524-
1525-
tx.execute(
1526-
"UPDATE benchmark_request SET status = $1 WHERE tag = $2;",
1527-
&[&benchmark_request_status, &benchmark_request.tag()],
1528-
)
1529-
.await
1530-
.context("failed to execute UPDATE benchmark_request")?;
1517+
let tag = request
1518+
.tag()
1519+
.expect("Cannot update status of a benchmark request without a tag. Use `attach_shas_to_try_benchmark_request` instead.");
15311520

1532-
tx.commit().await.context("failed to commit transaction")?;
1521+
let status_str = status.as_str();
1522+
let completed_at = status.completed_at();
1523+
self.conn()
1524+
.execute(
1525+
r#"
1526+
UPDATE benchmark_request
1527+
SET status = $1, completed_at = $2
1528+
WHERE tag = $3;"#,
1529+
&[&status_str, &completed_at, &tag],
1530+
)
1531+
.await
1532+
.context("failed to benchmark request status update")?;
15331533

15341534
Ok(())
15351535
}

site/src/job_queue.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,6 @@ async fn create_benchmark_request_releases(
129129
&name,
130130
date_time,
131131
BenchmarkRequestStatus::ArtifactsReady,
132-
"",
133-
"",
134132
);
135133
if let Err(e) = conn.insert_benchmark_request(&release_request).await {
136134
log::error!("Failed to insert release benchmark request: {}", e);
@@ -395,8 +393,6 @@ mod tests {
395393
tag,
396394
days_ago(age_days),
397395
BenchmarkRequestStatus::ArtifactsReady,
398-
"",
399-
"",
400396
)
401397
}
402398

0 commit comments

Comments
 (0)