20260612 优化CIR在线累计恢复性能

This commit is contained in:
2026-06-12 14:26:49 +08:00
parent 4047214ddf
commit 4e6bd687db
13 changed files with 715 additions and 63 deletions

View File

@@ -1,5 +1,5 @@
use crate::audit::DiscoveredFrom;
use crate::audit::PublicationPointAudit;
use crate::audit::{DiscoveredFrom, ObjectAuditEntry, PublicationPointAudit};
use crate::cir::{CirInputAccumulator, CirInputSnapshot};
use crate::data_model::rc::{AsResourceSet, IpResourceSet};
use crate::report::Warning;
use crate::validation::manifest::PublicationPointSource;
@@ -77,6 +77,8 @@ pub struct PublicationPointRunResult {
pub warnings: Vec<Warning>,
pub objects: ObjectsOutput,
pub audit: PublicationPointAudit,
pub cir_fresh_objects: Vec<ObjectAuditEntry>,
pub cir_cached_objects: Vec<ObjectAuditEntry>,
/// Candidate child CA instances to enqueue after this publication point completes.
///
/// - For `Fresh`, these are discovered from the current validated publication point.
@@ -126,6 +128,42 @@ pub struct TreeRunAuditOutput {
pub tree: TreeRunOutput,
pub publication_points: Vec<PublicationPointAudit>,
pub roa_cache_stats: RoaValidationCacheStats,
pub cir_input: CirInputSnapshot,
}
pub(crate) fn submit_publication_point_cir_input(
cir_input: &mut CirInputAccumulator,
source: PublicationPointSource,
audit: &PublicationPointAudit,
cir_fresh_objects: &[ObjectAuditEntry],
cir_cached_objects: &[ObjectAuditEntry],
) -> Result<(), TreeRunError> {
match source {
PublicationPointSource::Fresh => {
cir_input
.submit_audit_entries(crate::cir::CirInputSection::Fresh, &audit.objects)
.map_err(|e| TreeRunError::Runner(e.to_string()))?;
}
PublicationPointSource::FailedFetchNoCache => {
let entries = if cir_fresh_objects.is_empty() {
&audit.objects
} else {
cir_fresh_objects
};
cir_input
.submit_audit_entries(crate::cir::CirInputSection::Fresh, entries)
.map_err(|e| TreeRunError::Runner(e.to_string()))?;
}
PublicationPointSource::VcirCurrentInstance => {
cir_input
.submit_audit_entries(crate::cir::CirInputSection::Fresh, cir_fresh_objects)
.map_err(|e| TreeRunError::Runner(e.to_string()))?;
cir_input
.submit_audit_entries(crate::cir::CirInputSection::Cached, cir_cached_objects)
.map_err(|e| TreeRunError::Runner(e.to_string()))?;
}
}
Ok(())
}
pub fn run_tree_serial(
@@ -179,6 +217,7 @@ pub fn run_tree_serial_audit_multi_root(
let mut router_keys: Vec<RouterKeyPayload> = Vec::new();
let mut publication_points: Vec<PublicationPointAudit> = Vec::new();
let mut roa_cache_stats = RoaValidationCacheStats::default();
let mut cir_input = CirInputAccumulator::default();
while let Some(node) = queue.pop_front() {
let ca = &node.handle;
@@ -218,10 +257,20 @@ pub fn run_tree_serial_audit_multi_root(
aspas.extend(res.objects.aspas);
router_keys.extend(res.objects.router_keys);
let source = res.source;
let cir_fresh_objects = res.cir_fresh_objects;
let cir_cached_objects = res.cir_cached_objects;
let mut audit = res.audit;
audit.node_id = Some(node.id);
audit.parent_node_id = node.parent_id;
audit.discovered_from = node.discovered_from.clone();
submit_publication_point_cir_input(
&mut cir_input,
source,
&audit,
&cir_fresh_objects,
&cir_cached_objects,
)?;
if config.compact_audit {
audit.objects.clear();
audit.warnings.clear();
@@ -267,6 +316,7 @@ pub fn run_tree_serial_audit_multi_root(
},
publication_points,
roa_cache_stats,
cir_input: cir_input.finalize(),
})
}
@@ -274,7 +324,9 @@ pub fn run_tree_serial_audit_multi_root(
mod tests {
use std::sync::{Arc, Mutex};
use crate::audit::{DiscoveredFrom, PublicationPointAudit};
use crate::audit::{
AuditObjectKind, AuditObjectResult, DiscoveredFrom, ObjectAuditEntry, PublicationPointAudit,
};
use crate::validation::objects::{ObjectsOutput, ObjectsStats};
use super::{
@@ -353,6 +405,8 @@ mod tests {
roa_cache_stats: crate::validation::objects::RoaValidationCacheStats::default(),
},
audit: PublicationPointAudit::default(),
cir_fresh_objects: Vec::new(),
cir_cached_objects: Vec::new(),
discovered_children: children,
})
}
@@ -395,4 +449,114 @@ mod tests {
assert_eq!(out.tree.instances_processed, 2);
assert_eq!(out.publication_points.len(), 2);
}
#[test]
fn run_tree_serial_audit_accumulates_fresh_and_cached_cir_input() {
struct CirRunner;
impl PublicationPointRunner for CirRunner {
fn run_publication_point(
&self,
ca: &CaInstanceHandle,
) -> Result<PublicationPointRunResult, String> {
if ca.manifest_rsync_uri.ends_with("cached.mft") {
let fresh_reject = ObjectAuditEntry {
rsync_uri: "rsync://example.test/repo/cached/current.mft".to_string(),
sha256_hex: "11".repeat(32),
kind: AuditObjectKind::Manifest,
result: AuditObjectResult::Error,
detail: Some("fresh manifest rejected".to_string()),
};
let cached = ObjectAuditEntry {
rsync_uri: "rsync://example.test/repo/cached/old.roa".to_string(),
sha256_hex: "22".repeat(32),
kind: AuditObjectKind::Roa,
result: AuditObjectResult::Ok,
detail: None,
};
return Ok(PublicationPointRunResult {
source:
crate::validation::manifest::PublicationPointSource::VcirCurrentInstance,
snapshot: None,
warnings: Vec::new(),
objects: ObjectsOutput {
vrps: Vec::new(),
aspas: Vec::new(),
router_keys: Vec::new(),
local_outputs_cache: Vec::new(),
warnings: Vec::new(),
stats: ObjectsStats::default(),
audit: Vec::new(),
roa_cache_stats:
crate::validation::objects::RoaValidationCacheStats::default(),
},
audit: PublicationPointAudit {
objects: vec![fresh_reject.clone(), cached.clone()],
..PublicationPointAudit::default()
},
cir_fresh_objects: vec![fresh_reject],
cir_cached_objects: vec![cached],
discovered_children: Vec::new(),
});
}
let fresh = ObjectAuditEntry {
rsync_uri: "rsync://example.test/repo/fresh/a.roa".to_string(),
sha256_hex: "33".repeat(32),
kind: AuditObjectKind::Roa,
result: AuditObjectResult::Ok,
detail: None,
};
Ok(PublicationPointRunResult {
source: crate::validation::manifest::PublicationPointSource::Fresh,
snapshot: None,
warnings: Vec::new(),
objects: ObjectsOutput {
vrps: Vec::new(),
aspas: Vec::new(),
router_keys: Vec::new(),
local_outputs_cache: Vec::new(),
warnings: Vec::new(),
stats: ObjectsStats::default(),
audit: Vec::new(),
roa_cache_stats:
crate::validation::objects::RoaValidationCacheStats::default(),
},
audit: PublicationPointAudit {
objects: vec![fresh],
..PublicationPointAudit::default()
},
cir_fresh_objects: Vec::new(),
cir_cached_objects: Vec::new(),
discovered_children: Vec::new(),
})
}
}
let out = run_tree_serial_audit_multi_root(
vec![
sample_handle("rsync://example.test/repo/fresh/root.mft"),
sample_handle("rsync://example.test/repo/cached/cached.mft"),
],
&CirRunner,
&TreeRunConfig::default(),
)
.expect("tree run");
assert_eq!(out.cir_input.fresh_validated_objects.len(), 2);
assert_eq!(out.cir_input.cached_validated_objects.len(), 1);
assert_eq!(out.cir_input.fresh_rejected_objects.len(), 1);
assert!(
out.cir_input
.fresh_validated_objects
.iter()
.any(|item| item.rsync_uri == "rsync://example.test/repo/fresh/a.roa")
);
assert!(
out.cir_input
.cached_validated_objects
.iter()
.any(|item| item.rsync_uri == "rsync://example.test/repo/cached/old.roa")
);
}
}