Skip to content

Commit a4f5ad4

Browse files
authored
Merge pull request #2313 from Kobzol/remove-enqueue-parent-benchmark-job
Change error handling for creating parent jobs
2 parents 7cc7484 + 29c3b84 commit a4f5ad4

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);
@@ -241,20 +249,7 @@ pub trait Connection: Send + Sync {
241249
profile: Profile,
242250
benchmark_set: u32,
243251
kind: BenchmarkJobKind,
244-
) -> anyhow::Result<Option<u32>>;
245-
246-
/// Add a benchmark job which is explicitly using a `parent_sha` we split
247-
/// this out to improve our error handling. A `parent_sha` may not have
248-
/// an associated request in the `benchmarek`
249-
async fn enqueue_parent_benchmark_job(
250-
&self,
251-
parent_sha: &str,
252-
target: Target,
253-
backend: CodegenBackend,
254-
profile: Profile,
255-
benchmark_set: u32,
256-
kind: BenchmarkJobKind,
257-
) -> (bool, anyhow::Result<u32>);
252+
) -> JobEnqueueResult;
258253

259254
/// Returns a set of compile-time benchmark test cases that were already computed for the
260255
/// given artifact.
@@ -463,6 +458,15 @@ mod tests {
463458
}
464459
}
465460

461+
impl JobEnqueueResult {
462+
pub fn unwrap(self) -> u32 {
463+
match self {
464+
JobEnqueueResult::JobCreated(id) => id,
465+
error => panic!("Unexpected job enqueue result: {error:?}"),
466+
}
467+
}
468+
}
469+
466470
#[tokio::test]
467471
async fn pstat_returns_empty_vector_when_empty() {
468472
run_db_test(|ctx| async {
@@ -734,7 +738,10 @@ mod tests {
734738
BenchmarkJobKind::Runtime,
735739
)
736740
.await;
737-
assert!(result.is_ok());
741+
match result {
742+
JobEnqueueResult::JobCreated(_) => {}
743+
error => panic!("Invalid result: {error:?}"),
744+
}
738745

739746
Ok(ctx)
740747
})
@@ -880,16 +887,20 @@ mod tests {
880887
.unwrap();
881888

882889
// Now we can insert the job
883-
db.enqueue_benchmark_job(
884-
benchmark_request.tag().unwrap(),
885-
Target::X86_64UnknownLinuxGnu,
886-
CodegenBackend::Llvm,
887-
Profile::Opt,
888-
1u32,
889-
BenchmarkJobKind::Runtime,
890-
)
891-
.await
892-
.unwrap();
890+
match db
891+
.enqueue_benchmark_job(
892+
benchmark_request.tag().unwrap(),
893+
Target::X86_64UnknownLinuxGnu,
894+
CodegenBackend::Llvm,
895+
Profile::Opt,
896+
1u32,
897+
BenchmarkJobKind::Runtime,
898+
)
899+
.await
900+
{
901+
JobEnqueueResult::JobCreated(_) => {}
902+
error => panic!("Invalid result: {error:?}"),
903+
};
893904

894905
let (benchmark_job, artifact_id) = db
895906
.dequeue_benchmark_job(
@@ -1224,29 +1235,6 @@ mod tests {
12241235
.await;
12251236
}
12261237

1227-
#[tokio::test]
1228-
async fn enqueue_parent_benchmark_job() {
1229-
run_postgres_test(|ctx| async {
1230-
let db = ctx.db();
1231-
1232-
let (violates_foreign_key, _) = db
1233-
.enqueue_parent_benchmark_job(
1234-
"sha-0",
1235-
Target::X86_64UnknownLinuxGnu,
1236-
CodegenBackend::Llvm,
1237-
Profile::Debug,
1238-
0,
1239-
BenchmarkJobKind::Runtime,
1240-
)
1241-
.await;
1242-
1243-
assert!(violates_foreign_key);
1244-
1245-
Ok(ctx)
1246-
})
1247-
.await;
1248-
}
1249-
12501238
#[tokio::test]
12511239
async fn purge_artifact() {
12521240
run_postgres_test(|ctx| async {
@@ -1263,7 +1251,6 @@ mod tests {
12631251
BenchmarkJobKind::Compiletime,
12641252
)
12651253
.await
1266-
.unwrap()
12671254
.unwrap();
12681255
db.purge_artifact(&ArtifactId::Tag("foo".to_string())).await;
12691256

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)