Skip to content

Feat; job_queue table definition & mark a request as complete if all jobs are finished #2200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion database/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ aid benchmark error
1 syn-1.0.89 Failed to compile...
```


## New benchmarking design
We are currently implementing a new design for dispatching benchmarks to collector(s) and storing
them in the database. It will support new use-cases, like backfilling of new benchmarks into a parent
Expand Down Expand Up @@ -296,3 +295,36 @@ Columns:
* `completed`: Completed request.
* **backends** (`text NOT NULL`): Comma-separated list of codegen backends to benchmark. If empty, the default set of codegen backends will be benchmarked.
* **profiles** (`text NOT NULL`): Comma-separated list of profiles to benchmark. If empty, the default set of profiles will be benchmarked.

### job_queue

This table stores ephemeral benchmark jobs, which specifically tell the
collector which benchmarks it should execute. The jobs will be kept in the
table for ~30 days after being completed, so that we can quickly figure out
what master parent jobs we need to backfill when handling try builds.

Columns:

- **id** (`bigint` / `serial`): Primary-key identifier for the job row;
auto-increments with each new job.
- **request_id** (`bigint`): References the parent benchmark request that
spawned this job.
- **target** (`text NOT NULL`): Hardware/ISA the benchmarks must run on
(e.g. AArch64, x86_64).
- **backend** (`text NOT NULL`): Code generation backend the collector should
test (e.g. llvm, cranelift).
- **benchmark_set** (`int NOT NULL`): ID of the predefined benchmark suite to
execute.
- **collector_id** (`text`): Id of the collector that claimed the job
(populated once the job is started).
- **created_at** (`timestamptz NOT NULL`): Datetime when the job was queued.
- **started_at** (`timestamptz`): Datetime when the collector actually began
running the benchmarks; NULL until the job is claimed.
- **completed_at** (`timestampt`): Datetime when the collector finished
(successfully or otherwise); used to purge rows after ~30 days.
- **status** (`text NOT NULL`): Current job state. `queued`, `in_progress`,
`success`, or `failure`.
- **retry** (`int NOT NULL`): Number of times the job has been re-queued after
a failure; 0 on the first attempt.
- **error** (`text`): Optional error message or stack trace from the last
failed run; NULL when the job succeeded.
78 changes: 78 additions & 0 deletions database/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,10 @@ impl BenchmarkRequest {
pub fn is_release(&self) -> bool {
matches!(self.commit_type, BenchmarkRequestType::Release { .. })
}

pub fn is_completed(&self) -> bool {
matches!(self.status, BenchmarkRequestStatus::Completed { .. })
}
}

/// Cached information about benchmark requests in the DB
Expand All @@ -1009,4 +1013,78 @@ impl BenchmarkRequestIndex {
pub fn completed_requests(&self) -> &HashSet<String> {
&self.completed
}

pub fn add_tag(&mut self, tag: &str) {
self.all.insert(tag.to_string());
self.completed.insert(tag.to_string());
}
}

#[derive(Debug, Clone, PartialEq)]
pub enum BenchmarkJobStatus {
Queued,
InProgress,
Success,
Failure,
}

const BENCHMARK_JOB_STATUS_QUEUED_STR: &str = "queued";
const BENCHMARK_JOB_STATUS_IN_PROGRESS_STR: &str = "in_progress";
const BENCHMARK_JOB_STATUS_SUCCESS_STR: &str = "success";
const BENCHMARK_JOB_STATUS_FAILURE_STR: &str = "failure";

impl BenchmarkJobStatus {
pub fn as_str(&self) -> &str {
match self {
BenchmarkJobStatus::Queued => BENCHMARK_JOB_STATUS_QUEUED_STR,
BenchmarkJobStatus::InProgress => BENCHMARK_JOB_STATUS_IN_PROGRESS_STR,
BenchmarkJobStatus::Success => BENCHMARK_JOB_STATUS_SUCCESS_STR,
BenchmarkJobStatus::Failure => BENCHMARK_JOB_STATUS_FAILURE_STR,
}
}
}

impl fmt::Display for BenchmarkJobStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct BenchmarkSet(u32);

#[derive(Debug, Clone, PartialEq)]
pub struct BenchmarkJob {
target: Target,
backend: CodegenBackend,
benchmark_set: BenchmarkSet,
collector_id: String,
created_at: DateTime<Utc>,
started_at: Option<DateTime<Utc>>,
completed_at: Option<DateTime<Utc>>,
status: BenchmarkJobStatus,
retry: u32,
}

impl BenchmarkJob {
pub fn new(
target: Target,
backend: CodegenBackend,
benchmark_set: u32,
collector_id: &str,
created_at: DateTime<Utc>,
status: BenchmarkJobStatus,
) -> Self {
BenchmarkJob {
target,
backend,
benchmark_set: BenchmarkSet(benchmark_set),
collector_id: collector_id.to_string(),
created_at,
started_at: None,
completed_at: None,
status,
retry: 0,
}
}
}
Loading
Loading