Skip to content

Commit 29c3b84

Browse files
committed
Change error handling for creating parent jobs
1 parent 1208359 commit 29c3b84

File tree

5 files changed

+154
-187
lines changed

5 files changed

+154
-187
lines changed

database/src/pool.rs

Lines changed: 36 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ use tokio::sync::{OwnedSemaphorePermit, Semaphore};
1515
pub mod postgres;
1616
pub mod sqlite;
1717

18+
#[derive(Debug)]
19+
pub enum JobEnqueueResult {
20+
JobCreated(u32),
21+
JobAlreadyExisted,
22+
RequestShaNotFound { error: String },
23+
Other(anyhow::Error),
24+
}
25+
1826
#[async_trait::async_trait]
1927
pub trait Connection: Send + Sync {
2028
async fn maybe_create_indices(&mut self);
@@ -238,20 +246,7 @@ pub trait Connection: Send + Sync {
238246
profile: Profile,
239247
benchmark_set: u32,
240248
kind: BenchmarkJobKind,
241-
) -> anyhow::Result<Option<u32>>;
242-
243-
/// Add a benchmark job which is explicitly using a `parent_sha` we split
244-
/// this out to improve our error handling. A `parent_sha` may not have
245-
/// an associated request in the `benchmarek`
246-
async fn enqueue_parent_benchmark_job(
247-
&self,
248-
parent_sha: &str,
249-
target: Target,
250-
backend: CodegenBackend,
251-
profile: Profile,
252-
benchmark_set: u32,
253-
kind: BenchmarkJobKind,
254-
) -> (bool, anyhow::Result<u32>);
249+
) -> JobEnqueueResult;
255250

256251
/// Returns a set of compile-time benchmark test cases that were already computed for the
257252
/// given artifact.
@@ -460,6 +455,15 @@ mod tests {
460455
}
461456
}
462457

458+
impl JobEnqueueResult {
459+
pub fn unwrap(self) -> u32 {
460+
match self {
461+
JobEnqueueResult::JobCreated(id) => id,
462+
error => panic!("Unexpected job enqueue result: {error:?}"),
463+
}
464+
}
465+
}
466+
463467
#[tokio::test]
464468
async fn pstat_returns_empty_vector_when_empty() {
465469
run_db_test(|ctx| async {
@@ -715,7 +719,10 @@ mod tests {
715719
BenchmarkJobKind::Runtime,
716720
)
717721
.await;
718-
assert!(result.is_ok());
722+
match result {
723+
JobEnqueueResult::JobCreated(_) => {}
724+
error => panic!("Invalid result: {error:?}"),
725+
}
719726

720727
Ok(ctx)
721728
})
@@ -861,16 +868,20 @@ mod tests {
861868
.unwrap();
862869

863870
// Now we can insert the job
864-
db.enqueue_benchmark_job(
865-
benchmark_request.tag().unwrap(),
866-
Target::X86_64UnknownLinuxGnu,
867-
CodegenBackend::Llvm,
868-
Profile::Opt,
869-
1u32,
870-
BenchmarkJobKind::Runtime,
871-
)
872-
.await
873-
.unwrap();
871+
match db
872+
.enqueue_benchmark_job(
873+
benchmark_request.tag().unwrap(),
874+
Target::X86_64UnknownLinuxGnu,
875+
CodegenBackend::Llvm,
876+
Profile::Opt,
877+
1u32,
878+
BenchmarkJobKind::Runtime,
879+
)
880+
.await
881+
{
882+
JobEnqueueResult::JobCreated(_) => {}
883+
error => panic!("Invalid result: {error:?}"),
884+
};
874885

875886
let (benchmark_job, artifact_id) = db
876887
.dequeue_benchmark_job(
@@ -1205,29 +1216,6 @@ mod tests {
12051216
.await;
12061217
}
12071218

1208-
#[tokio::test]
1209-
async fn enqueue_parent_benchmark_job() {
1210-
run_postgres_test(|ctx| async {
1211-
let db = ctx.db();
1212-
1213-
let (violates_foreign_key, _) = db
1214-
.enqueue_parent_benchmark_job(
1215-
"sha-0",
1216-
Target::X86_64UnknownLinuxGnu,
1217-
CodegenBackend::Llvm,
1218-
Profile::Debug,
1219-
0,
1220-
BenchmarkJobKind::Runtime,
1221-
)
1222-
.await;
1223-
1224-
assert!(violates_foreign_key);
1225-
1226-
Ok(ctx)
1227-
})
1228-
.await;
1229-
}
1230-
12311219
#[tokio::test]
12321220
async fn purge_artifact() {
12331221
run_postgres_test(|ctx| async {
@@ -1244,7 +1232,6 @@ mod tests {
12441232
BenchmarkJobKind::Compiletime,
12451233
)
12461234
.await
1247-
.unwrap()
12481235
.unwrap();
12491236
db.purge_artifact(&ArtifactId::Tag("foo".to_string())).await;
12501237

database/src/pool/postgres.rs

Lines changed: 21 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::pool::{Connection, ConnectionManager, ManagedConnection, Transaction};
1+
use crate::pool::{
2+
Connection, ConnectionManager, JobEnqueueResult, ManagedConnection, Transaction,
3+
};
24
use crate::selector::CompileTestCase;
35
use crate::{
46
ArtifactCollection, ArtifactId, ArtifactIdNumber, Benchmark, BenchmarkJob,
@@ -1773,18 +1775,19 @@ where
17731775
})
17741776
}
17751777

1776-
async fn enqueue_parent_benchmark_job(
1778+
async fn enqueue_benchmark_job(
17771779
&self,
1778-
parent_sha: &str,
1780+
request_tag: &str,
17791781
target: Target,
17801782
backend: CodegenBackend,
17811783
profile: Profile,
17821784
benchmark_set: u32,
17831785
kind: BenchmarkJobKind,
1784-
) -> (bool, anyhow::Result<u32>) {
1785-
let row_result = self
1786+
) -> JobEnqueueResult {
1787+
// This will return zero rows if the job already exists
1788+
let result = self
17861789
.conn()
1787-
.query_one(
1790+
.query(
17881791
r#"
17891792
INSERT INTO job_queue(
17901793
request_tag,
@@ -1800,7 +1803,7 @@ where
18001803
RETURNING job_queue.id
18011804
"#,
18021805
&[
1803-
&parent_sha,
1806+
&request_tag,
18041807
&target,
18051808
&backend,
18061809
&profile,
@@ -1811,75 +1814,28 @@ where
18111814
)
18121815
.await;
18131816

1814-
match row_result {
1815-
Ok(row) => (false, Ok(row.get::<_, i32>(0) as u32)),
1817+
match result {
1818+
Ok(rows) => {
1819+
let Some(row) = rows.into_iter().next() else {
1820+
return JobEnqueueResult::JobAlreadyExisted;
1821+
};
1822+
JobEnqueueResult::JobCreated(row.get::<_, i32>(0) as u32)
1823+
}
18161824
Err(e) => {
18171825
if let Some(db_err) = e.as_db_error() {
18181826
if db_err.code() == &SqlState::FOREIGN_KEY_VIOLATION {
18191827
let constraint = db_err.constraint().unwrap_or("benchmark_tag constraint");
18201828
let detail = db_err.detail().unwrap_or("");
1821-
return (
1822-
true,
1823-
Err(anyhow::anyhow!(
1824-
"Foreign key violation on {} for request_tag='{}'. {}",
1825-
constraint,
1826-
parent_sha,
1827-
detail
1828-
)),
1829-
);
1829+
return JobEnqueueResult::RequestShaNotFound {
1830+
error: format!("Foreign key violation on `{constraint}`: {detail}"),
1831+
};
18301832
}
18311833
}
1832-
(false, Err(e.into()))
1834+
JobEnqueueResult::Other(e.into())
18331835
}
18341836
}
18351837
}
18361838

1837-
async fn enqueue_benchmark_job(
1838-
&self,
1839-
request_tag: &str,
1840-
target: Target,
1841-
backend: CodegenBackend,
1842-
profile: Profile,
1843-
benchmark_set: u32,
1844-
kind: BenchmarkJobKind,
1845-
) -> anyhow::Result<Option<u32>> {
1846-
// This will return zero rows if the job already exists
1847-
let rows = self
1848-
.conn()
1849-
.query(
1850-
r#"
1851-
INSERT INTO job_queue(
1852-
request_tag,
1853-
target,
1854-
backend,
1855-
profile,
1856-
benchmark_set,
1857-
status,
1858-
kind
1859-
)
1860-
VALUES ($1, $2, $3, $4, $5, $6, $7)
1861-
ON CONFLICT DO NOTHING
1862-
RETURNING job_queue.id
1863-
"#,
1864-
&[
1865-
&request_tag,
1866-
&target,
1867-
&backend,
1868-
&profile,
1869-
&(benchmark_set as i32),
1870-
&BENCHMARK_JOB_STATUS_QUEUED_STR,
1871-
&kind,
1872-
],
1873-
)
1874-
.await
1875-
.context("failed to insert benchmark_job")?;
1876-
if let Some(row) = rows.first() {
1877-
Ok(Some(row.get::<_, i32>(0) as u32))
1878-
} else {
1879-
Ok(None)
1880-
}
1881-
}
1882-
18831839
async fn get_compile_test_cases_with_measurements(
18841840
&self,
18851841
artifact_row_id: &ArtifactIdNumber,

database/src/pool/sqlite.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::pool::{Connection, ConnectionManager, ManagedConnection, Transaction};
1+
use crate::pool::{
2+
Connection, ConnectionManager, JobEnqueueResult, ManagedConnection, Transaction,
3+
};
24
use crate::selector::CompileTestCase;
35
use crate::{
46
ArtifactCollection, ArtifactId, Benchmark, BenchmarkJob, BenchmarkJobConclusion,
@@ -1356,19 +1358,7 @@ impl Connection for SqliteConnection {
13561358
_profile: Profile,
13571359
_benchmark_set: u32,
13581360
_kind: BenchmarkJobKind,
1359-
) -> anyhow::Result<Option<u32>> {
1360-
no_queue_implementation_abort!()
1361-
}
1362-
1363-
async fn enqueue_parent_benchmark_job(
1364-
&self,
1365-
_parent_sha: &str,
1366-
_target: Target,
1367-
_backend: CodegenBackend,
1368-
_profile: Profile,
1369-
_benchmark_set: u32,
1370-
_kind: BenchmarkJobKind,
1371-
) -> (bool, anyhow::Result<u32>) {
1361+
) -> JobEnqueueResult {
13721362
no_queue_implementation_abort!()
13731363
}
13741364

database/src/tests/builder.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::pool::JobEnqueueResult;
12
use crate::{
23
BenchmarkJob, BenchmarkJobConclusion, BenchmarkJobKind, BenchmarkRequest,
34
BenchmarkRequestStatus, BenchmarkSet, CodegenBackend, CollectorConfig, Connection, Profile,
@@ -40,7 +41,7 @@ impl RequestBuilder {
4041

4142
pub async fn add_jobs(mut self, db: &dyn Connection, jobs: &[JobBuilder]) -> Self {
4243
for job in jobs {
43-
let id = db
44+
let id = match db
4445
.enqueue_benchmark_job(
4546
self.tag(),
4647
job.target,
@@ -50,8 +51,11 @@ impl RequestBuilder {
5051
job.kind,
5152
)
5253
.await
53-
.unwrap();
54-
self.jobs.push((job.clone(), id.unwrap()));
54+
{
55+
JobEnqueueResult::JobCreated(id) => id,
56+
error => panic!("Unexpected job enqueue result: {error:?}"),
57+
};
58+
self.jobs.push((job.clone(), id));
5559
}
5660
self
5761
}

0 commit comments

Comments
 (0)