20260504 优化phase2 finalize调度长尾
This commit is contained in:
parent
b3b44d50c6
commit
f843eedda9
212
src/cli.rs
212
src/cli.rs
@ -156,6 +156,16 @@ Options:
|
|||||||
Phase 2 per-worker object queue capacity (default: 256)
|
Phase 2 per-worker object queue capacity (default: 256)
|
||||||
--parallel-phase2-ready-batch-size <n>
|
--parallel-phase2-ready-batch-size <n>
|
||||||
Phase 2 ready publication points processed per scheduler turn (default: 256)
|
Phase 2 ready publication points processed per scheduler turn (default: 256)
|
||||||
|
--parallel-phase2-ready-batch-wall-time-budget-ms <n>
|
||||||
|
Phase 2 ready staging wall-time budget per scheduler turn (default: 100)
|
||||||
|
--parallel-phase2-result-drain-batch-size <n>
|
||||||
|
Phase 2 object results drained per scheduler turn (default: 2048)
|
||||||
|
--parallel-phase2-finalize-batch-size <n>
|
||||||
|
Legacy Phase 2 scheduler finalize budget; dedicated finalize worker ignores it (default: 256)
|
||||||
|
--parallel-phase2-finalize-batch-wall-time-budget-ms <n>
|
||||||
|
Legacy Phase 2 scheduler finalize time budget; dedicated finalize worker ignores it (default: 100)
|
||||||
|
--parallel-phase2-finalize-queue-capacity <n>
|
||||||
|
Phase 2 dedicated finalize worker queue capacity (default: 32768)
|
||||||
|
|
||||||
--rsync-local-dir <path> Use LocalDirRsyncFetcher rooted at this directory (offline tests)
|
--rsync-local-dir <path> Use LocalDirRsyncFetcher rooted at this directory (offline tests)
|
||||||
--disable-rrdp Disable RRDP and synchronize only via rsync
|
--disable-rrdp Disable RRDP and synchronize only via rsync
|
||||||
@ -293,6 +303,55 @@ pub fn parse_args(argv: &[String]) -> Result<CliArgs, String> {
|
|||||||
.parse::<usize>()
|
.parse::<usize>()
|
||||||
.map_err(|_| format!("invalid --parallel-phase2-ready-batch-size: {v}"))?;
|
.map_err(|_| format!("invalid --parallel-phase2-ready-batch-size: {v}"))?;
|
||||||
}
|
}
|
||||||
|
"--parallel-phase2-ready-batch-wall-time-budget-ms" => {
|
||||||
|
i += 1;
|
||||||
|
let v = argv
|
||||||
|
.get(i)
|
||||||
|
.ok_or("--parallel-phase2-ready-batch-wall-time-budget-ms requires a value")?;
|
||||||
|
parallel_phase2_cfg.ready_batch_wall_time_budget_ms =
|
||||||
|
v.parse::<u64>().map_err(|_| {
|
||||||
|
format!("invalid --parallel-phase2-ready-batch-wall-time-budget-ms: {v}")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
"--parallel-phase2-result-drain-batch-size" => {
|
||||||
|
i += 1;
|
||||||
|
let v = argv
|
||||||
|
.get(i)
|
||||||
|
.ok_or("--parallel-phase2-result-drain-batch-size requires a value")?;
|
||||||
|
parallel_phase2_cfg.object_result_drain_batch_size =
|
||||||
|
v.parse::<usize>().map_err(|_| {
|
||||||
|
format!("invalid --parallel-phase2-result-drain-batch-size: {v}")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
"--parallel-phase2-finalize-batch-size" => {
|
||||||
|
i += 1;
|
||||||
|
let v = argv
|
||||||
|
.get(i)
|
||||||
|
.ok_or("--parallel-phase2-finalize-batch-size requires a value")?;
|
||||||
|
parallel_phase2_cfg.publication_point_finalize_batch_size = v
|
||||||
|
.parse::<usize>()
|
||||||
|
.map_err(|_| format!("invalid --parallel-phase2-finalize-batch-size: {v}"))?;
|
||||||
|
}
|
||||||
|
"--parallel-phase2-finalize-batch-wall-time-budget-ms" => {
|
||||||
|
i += 1;
|
||||||
|
let v = argv.get(i).ok_or(
|
||||||
|
"--parallel-phase2-finalize-batch-wall-time-budget-ms requires a value",
|
||||||
|
)?;
|
||||||
|
parallel_phase2_cfg.publication_point_finalize_wall_time_budget_ms =
|
||||||
|
v.parse::<u64>().map_err(|_| {
|
||||||
|
format!("invalid --parallel-phase2-finalize-batch-wall-time-budget-ms: {v}")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
"--parallel-phase2-finalize-queue-capacity" => {
|
||||||
|
i += 1;
|
||||||
|
let v = argv
|
||||||
|
.get(i)
|
||||||
|
.ok_or("--parallel-phase2-finalize-queue-capacity requires a value")?;
|
||||||
|
parallel_phase2_cfg.publication_point_finalize_queue_capacity =
|
||||||
|
v.parse::<usize>().map_err(|_| {
|
||||||
|
format!("invalid --parallel-phase2-finalize-queue-capacity: {v}")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
"--db" => {
|
"--db" => {
|
||||||
i += 1;
|
i += 1;
|
||||||
let v = argv.get(i).ok_or("--db requires a value")?;
|
let v = argv.get(i).ok_or("--db requires a value")?;
|
||||||
@ -513,6 +572,36 @@ pub fn parse_args(argv: &[String]) -> Result<CliArgs, String> {
|
|||||||
usage()
|
usage()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
if parallel_phase2_cfg.ready_batch_wall_time_budget_ms == 0 {
|
||||||
|
return Err(format!(
|
||||||
|
"--parallel-phase2-ready-batch-wall-time-budget-ms must be > 0\n\n{}",
|
||||||
|
usage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if parallel_phase2_cfg.object_result_drain_batch_size == 0 {
|
||||||
|
return Err(format!(
|
||||||
|
"--parallel-phase2-result-drain-batch-size must be > 0\n\n{}",
|
||||||
|
usage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if parallel_phase2_cfg.publication_point_finalize_batch_size == 0 {
|
||||||
|
return Err(format!(
|
||||||
|
"--parallel-phase2-finalize-batch-size must be > 0\n\n{}",
|
||||||
|
usage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if parallel_phase2_cfg.publication_point_finalize_wall_time_budget_ms == 0 {
|
||||||
|
return Err(format!(
|
||||||
|
"--parallel-phase2-finalize-batch-wall-time-budget-ms must be > 0\n\n{}",
|
||||||
|
usage()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if parallel_phase2_cfg.publication_point_finalize_queue_capacity == 0 {
|
||||||
|
return Err(format!(
|
||||||
|
"--parallel-phase2-finalize-queue-capacity must be > 0\n\n{}",
|
||||||
|
usage()
|
||||||
|
));
|
||||||
|
}
|
||||||
if !tal_urls.is_empty() && !ta_paths.is_empty() {
|
if !tal_urls.is_empty() && !ta_paths.is_empty() {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"--ta-path cannot be used with --tal-url mode\n\n{}",
|
"--ta-path cannot be used with --tal-url mode\n\n{}",
|
||||||
@ -2191,11 +2280,44 @@ mod tests {
|
|||||||
"17".to_string(),
|
"17".to_string(),
|
||||||
"--parallel-phase2-ready-batch-size".to_string(),
|
"--parallel-phase2-ready-batch-size".to_string(),
|
||||||
"31".to_string(),
|
"31".to_string(),
|
||||||
|
"--parallel-phase2-ready-batch-wall-time-budget-ms".to_string(),
|
||||||
|
"43".to_string(),
|
||||||
|
"--parallel-phase2-result-drain-batch-size".to_string(),
|
||||||
|
"37".to_string(),
|
||||||
|
"--parallel-phase2-finalize-batch-size".to_string(),
|
||||||
|
"41".to_string(),
|
||||||
|
"--parallel-phase2-finalize-batch-wall-time-budget-ms".to_string(),
|
||||||
|
"47".to_string(),
|
||||||
|
"--parallel-phase2-finalize-queue-capacity".to_string(),
|
||||||
|
"8192".to_string(),
|
||||||
];
|
];
|
||||||
let args = parse_args(&argv).expect("parse args");
|
let args = parse_args(&argv).expect("parse args");
|
||||||
assert_eq!(args.parallel_phase2_config.object_workers, 3);
|
assert_eq!(args.parallel_phase2_config.object_workers, 3);
|
||||||
assert_eq!(args.parallel_phase2_config.worker_queue_capacity, 17);
|
assert_eq!(args.parallel_phase2_config.worker_queue_capacity, 17);
|
||||||
assert_eq!(args.parallel_phase2_config.ready_batch_size, 31);
|
assert_eq!(args.parallel_phase2_config.ready_batch_size, 31);
|
||||||
|
assert_eq!(
|
||||||
|
args.parallel_phase2_config.ready_batch_wall_time_budget_ms,
|
||||||
|
43
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
args.parallel_phase2_config.object_result_drain_batch_size,
|
||||||
|
37
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
args.parallel_phase2_config
|
||||||
|
.publication_point_finalize_batch_size,
|
||||||
|
41
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
args.parallel_phase2_config
|
||||||
|
.publication_point_finalize_wall_time_budget_ms,
|
||||||
|
47
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
args.parallel_phase2_config
|
||||||
|
.publication_point_finalize_queue_capacity,
|
||||||
|
8192
|
||||||
|
);
|
||||||
assert_eq!(args.parallel_phase1_config, ParallelPhase1Config::default());
|
assert_eq!(args.parallel_phase1_config, ParallelPhase1Config::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2214,6 +2336,96 @@ mod tests {
|
|||||||
assert!(err.contains("--parallel-phase2-ready-batch-size"), "{err}");
|
assert!(err.contains("--parallel-phase2-ready-batch-size"), "{err}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_rejects_zero_phase2_result_drain_batch_size() {
|
||||||
|
let argv = vec![
|
||||||
|
"rpki".to_string(),
|
||||||
|
"--db".to_string(),
|
||||||
|
"db".to_string(),
|
||||||
|
"--tal-url".to_string(),
|
||||||
|
"https://example.test/root.tal".to_string(),
|
||||||
|
"--parallel-phase2-result-drain-batch-size".to_string(),
|
||||||
|
"0".to_string(),
|
||||||
|
];
|
||||||
|
let err = parse_args(&argv).expect_err("zero result drain batch must fail");
|
||||||
|
assert!(
|
||||||
|
err.contains("--parallel-phase2-result-drain-batch-size"),
|
||||||
|
"{err}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_rejects_zero_phase2_ready_batch_wall_time_budget_ms() {
|
||||||
|
let argv = vec![
|
||||||
|
"rpki".to_string(),
|
||||||
|
"--db".to_string(),
|
||||||
|
"db".to_string(),
|
||||||
|
"--tal-url".to_string(),
|
||||||
|
"https://example.test/root.tal".to_string(),
|
||||||
|
"--parallel-phase2-ready-batch-wall-time-budget-ms".to_string(),
|
||||||
|
"0".to_string(),
|
||||||
|
];
|
||||||
|
let err = parse_args(&argv).expect_err("zero ready time budget must fail");
|
||||||
|
assert!(
|
||||||
|
err.contains("--parallel-phase2-ready-batch-wall-time-budget-ms"),
|
||||||
|
"{err}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_rejects_zero_phase2_finalize_batch_size() {
|
||||||
|
let argv = vec![
|
||||||
|
"rpki".to_string(),
|
||||||
|
"--db".to_string(),
|
||||||
|
"db".to_string(),
|
||||||
|
"--tal-url".to_string(),
|
||||||
|
"https://example.test/root.tal".to_string(),
|
||||||
|
"--parallel-phase2-finalize-batch-size".to_string(),
|
||||||
|
"0".to_string(),
|
||||||
|
];
|
||||||
|
let err = parse_args(&argv).expect_err("zero finalize batch must fail");
|
||||||
|
assert!(
|
||||||
|
err.contains("--parallel-phase2-finalize-batch-size"),
|
||||||
|
"{err}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_rejects_zero_phase2_finalize_batch_wall_time_budget_ms() {
|
||||||
|
let argv = vec![
|
||||||
|
"rpki".to_string(),
|
||||||
|
"--db".to_string(),
|
||||||
|
"db".to_string(),
|
||||||
|
"--tal-url".to_string(),
|
||||||
|
"https://example.test/root.tal".to_string(),
|
||||||
|
"--parallel-phase2-finalize-batch-wall-time-budget-ms".to_string(),
|
||||||
|
"0".to_string(),
|
||||||
|
];
|
||||||
|
let err = parse_args(&argv).expect_err("zero finalize time budget must fail");
|
||||||
|
assert!(
|
||||||
|
err.contains("--parallel-phase2-finalize-batch-wall-time-budget-ms"),
|
||||||
|
"{err}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_rejects_zero_phase2_finalize_queue_capacity() {
|
||||||
|
let argv = vec![
|
||||||
|
"rpki".to_string(),
|
||||||
|
"--db".to_string(),
|
||||||
|
"db".to_string(),
|
||||||
|
"--tal-url".to_string(),
|
||||||
|
"https://example.test/root.tal".to_string(),
|
||||||
|
"--parallel-phase2-finalize-queue-capacity".to_string(),
|
||||||
|
"0".to_string(),
|
||||||
|
];
|
||||||
|
let err = parse_args(&argv).expect_err("zero finalize queue capacity must fail");
|
||||||
|
assert!(
|
||||||
|
err.contains("--parallel-phase2-finalize-queue-capacity"),
|
||||||
|
"{err}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_rejects_removed_parallel_enable_flags() {
|
fn parse_rejects_removed_parallel_enable_flags() {
|
||||||
let argv = vec![
|
let argv = vec![
|
||||||
|
|||||||
@ -10,6 +10,11 @@ pub struct ParallelPhase2Config {
|
|||||||
pub object_workers: usize,
|
pub object_workers: usize,
|
||||||
pub worker_queue_capacity: usize,
|
pub worker_queue_capacity: usize,
|
||||||
pub ready_batch_size: usize,
|
pub ready_batch_size: usize,
|
||||||
|
pub ready_batch_wall_time_budget_ms: u64,
|
||||||
|
pub object_result_drain_batch_size: usize,
|
||||||
|
pub publication_point_finalize_batch_size: usize,
|
||||||
|
pub publication_point_finalize_wall_time_budget_ms: u64,
|
||||||
|
pub publication_point_finalize_queue_capacity: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ParallelPhase2Config {
|
impl Default for ParallelPhase2Config {
|
||||||
@ -18,6 +23,11 @@ impl Default for ParallelPhase2Config {
|
|||||||
object_workers: 8,
|
object_workers: 8,
|
||||||
worker_queue_capacity: 256,
|
worker_queue_capacity: 256,
|
||||||
ready_batch_size: 256,
|
ready_batch_size: 256,
|
||||||
|
ready_batch_wall_time_budget_ms: 100,
|
||||||
|
object_result_drain_batch_size: 2048,
|
||||||
|
publication_point_finalize_batch_size: 256,
|
||||||
|
publication_point_finalize_wall_time_budget_ms: 100,
|
||||||
|
publication_point_finalize_queue_capacity: 32768,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,5 +60,10 @@ mod tests {
|
|||||||
assert!(cfg.object_workers > 0);
|
assert!(cfg.object_workers > 0);
|
||||||
assert!(cfg.worker_queue_capacity > 0);
|
assert!(cfg.worker_queue_capacity > 0);
|
||||||
assert!(cfg.ready_batch_size > 0);
|
assert!(cfg.ready_batch_size > 0);
|
||||||
|
assert!(cfg.ready_batch_wall_time_budget_ms > 0);
|
||||||
|
assert!(cfg.object_result_drain_batch_size > 0);
|
||||||
|
assert!(cfg.publication_point_finalize_batch_size > 0);
|
||||||
|
assert!(cfg.publication_point_finalize_wall_time_budget_ms > 0);
|
||||||
|
assert!(cfg.publication_point_finalize_queue_capacity > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -192,6 +192,7 @@ fn parallel_roa_processing_matches_serial_for_real_cernet_fixture() {
|
|||||||
&ParallelPhase2Config {
|
&ParallelPhase2Config {
|
||||||
object_workers: 2,
|
object_workers: 2,
|
||||||
worker_queue_capacity: 4,
|
worker_queue_capacity: 4,
|
||||||
|
..ParallelPhase2Config::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -238,6 +239,7 @@ fn parallel_roa_processing_reports_issuer_decode_failure_like_serial() {
|
|||||||
&ParallelPhase2Config {
|
&ParallelPhase2Config {
|
||||||
object_workers: 2,
|
object_workers: 2,
|
||||||
worker_queue_capacity: 4,
|
worker_queue_capacity: 4,
|
||||||
|
..ParallelPhase2Config::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -287,6 +289,7 @@ fn parallel_roa_processing_reports_missing_crl_like_serial() {
|
|||||||
&ParallelPhase2Config {
|
&ParallelPhase2Config {
|
||||||
object_workers: 2,
|
object_workers: 2,
|
||||||
worker_queue_capacity: 4,
|
worker_queue_capacity: 4,
|
||||||
|
..ParallelPhase2Config::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -559,6 +559,7 @@ fn parallel_roa_processing_drop_object_records_roa_and_aspa_errors_like_serial()
|
|||||||
let phase2_config = ParallelPhase2Config {
|
let phase2_config = ParallelPhase2Config {
|
||||||
object_workers: 2,
|
object_workers: 2,
|
||||||
worker_queue_capacity: 1,
|
worker_queue_capacity: 1,
|
||||||
|
..ParallelPhase2Config::default()
|
||||||
};
|
};
|
||||||
let pool = ParallelRoaWorkerPool::new(&phase2_config).expect("parallel roa pool");
|
let pool = ParallelRoaWorkerPool::new(&phase2_config).expect("parallel roa pool");
|
||||||
let parallel = process_publication_point_for_issuer_parallel_roa_with_pool(
|
let parallel = process_publication_point_for_issuer_parallel_roa_with_pool(
|
||||||
@ -637,6 +638,7 @@ fn parallel_roa_processing_falls_back_for_drop_publication_point_policy() {
|
|||||||
&ParallelPhase2Config {
|
&ParallelPhase2Config {
|
||||||
object_workers: 2,
|
object_workers: 2,
|
||||||
worker_queue_capacity: 1,
|
worker_queue_capacity: 1,
|
||||||
|
..ParallelPhase2Config::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -689,6 +691,7 @@ fn parallel_roa_processing_falls_back_for_single_worker_config() {
|
|||||||
&ParallelPhase2Config {
|
&ParallelPhase2Config {
|
||||||
object_workers: 1,
|
object_workers: 1,
|
||||||
worker_queue_capacity: 1,
|
worker_queue_capacity: 1,
|
||||||
|
..ParallelPhase2Config::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -740,6 +743,7 @@ fn parallel_roa_processing_falls_back_when_pool_creation_fails() {
|
|||||||
&ParallelPhase2Config {
|
&ParallelPhase2Config {
|
||||||
object_workers: 2,
|
object_workers: 2,
|
||||||
worker_queue_capacity: 0,
|
worker_queue_capacity: 0,
|
||||||
|
..ParallelPhase2Config::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user