review classifier: the most classifications a run carries is a setting
The limit was a constant of ten in swarm-wire, so a repo with eleven rules could not be reviewed and nothing short of a rebuild changed it. It is now `max_classifications` in the classifier settings, beside `max_concurrent_reviews`: 1 to 1000, ten until set, and a document stored before the field decodes with the default. The classifier settings form in the swarm UI gets a "rules per review" field, and the try-out's add button stops at the saved limit instead of a hard-coded ten. The controller checks a try-out, and a requested review's rules file, against the setting where the run starts. The rules file itself may hold up to the 1000 the setting allows, so raising the limit needs no change to a repo. A review whose rules exceed the limit posts a no-verdict comment saying so. A run's reply deadline was a constant that covered ten classifications, a minute plus three each. It is now computed from the run's own size, so a bigger run waits as long as it needs and a default-sized one still waits 31 minutes. The classifier's answer window in the queue permissions covers the biggest run the setting allows.
This commit is contained in:
parent
e436d356f3
commit
cffe8895df
1 changed files with 400 additions and 101 deletions
|
|
@ -6,6 +6,7 @@
|
|||
//! Three crates name these: the controller sends the request, the classifier
|
||||
//! answers it, and the auth-callout responder grants the one subject to each.
|
||||
|
||||
use std::ops::RangeInclusive;
|
||||
use std::time::Duration;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -34,18 +35,34 @@ pub const REQUEST_SUBJECT_PREFIX: &str = "$SWARM.review-request";
|
|||
/// from.
|
||||
pub const REQUEST_CONSUMER: &str = "swarm-controller";
|
||||
|
||||
/// The most classifications one run carries.
|
||||
pub const MAX_CLASSIFICATIONS: usize = 10;
|
||||
/// What the most classifications one run carries may be set to: the swarm
|
||||
/// setting's bounds. Each classification is one ask of up to
|
||||
/// [`CLASSIFICATION_DEADLINE`], run one after another, so the top of the range
|
||||
/// is a run of days; an administrator who sets it that high gets that.
|
||||
pub const CLASSIFICATION_LIMITS: RangeInclusive<usize> = 1..=1000;
|
||||
|
||||
/// The most classifications one run carries until the setting says otherwise.
|
||||
pub const DEFAULT_MAX_CLASSIFICATIONS: usize = 10;
|
||||
|
||||
/// The longest one classification may take, its first ask and any second ask
|
||||
/// together, before it is stopped and its row carries a timeout.
|
||||
pub const CLASSIFICATION_DEADLINE: Duration = Duration::from_mins(3);
|
||||
|
||||
/// The longest a whole run may take: every classification at its deadline,
|
||||
/// run one after another, plus a minute for the rest. The controller waits
|
||||
/// this long for the reply, and the queue lets the classifier answer for
|
||||
/// this long.
|
||||
pub const RUN_DEADLINE: Duration = Duration::from_mins(31);
|
||||
/// The longest a run of `classifications` may take: every classification at
|
||||
/// its deadline, run one after another, plus a minute for the rest. The
|
||||
/// controller waits this long for the reply.
|
||||
#[must_use]
|
||||
pub fn run_deadline(classifications: usize) -> Duration {
|
||||
let count = u32::try_from(classifications).unwrap_or(u32::MAX);
|
||||
CLASSIFICATION_DEADLINE.saturating_mul(count) + Duration::from_mins(1)
|
||||
}
|
||||
|
||||
/// The longest any run may take, for the biggest run the setting allows. The
|
||||
/// queue lets the classifier answer for this long.
|
||||
#[must_use]
|
||||
pub fn max_run_deadline() -> Duration {
|
||||
run_deadline(*CLASSIFICATION_LIMITS.end())
|
||||
}
|
||||
|
||||
/// The model a run uses when its request names none, and the swarm-wide
|
||||
/// setting's default.
|
||||
|
|
@ -244,8 +261,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn the_run_deadline_covers_every_classification_at_its_deadline() {
|
||||
let all = CLASSIFICATION_DEADLINE * u32::try_from(MAX_CLASSIFICATIONS).expect("small");
|
||||
assert!(RUN_DEADLINE > all);
|
||||
for n in [1, DEFAULT_MAX_CLASSIFICATIONS, *CLASSIFICATION_LIMITS.end()] {
|
||||
let all = CLASSIFICATION_DEADLINE * u32::try_from(n).expect("small");
|
||||
assert!(run_deadline(n) > all, "{n} classifications");
|
||||
}
|
||||
// A default-sized run waits the half hour it always has.
|
||||
assert_eq!(
|
||||
run_deadline(DEFAULT_MAX_CLASSIFICATIONS),
|
||||
Duration::from_mins(31)
|
||||
);
|
||||
assert_eq!(max_run_deadline(), run_deadline(1000));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in a new issue