20260620 优化delta长尾控制面和PP cache快路径
This commit is contained in:
@@ -79,6 +79,11 @@ impl TimingHandle {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn report_snapshot(&self, top_n: usize) -> TimingReportV1 {
|
||||
let g = self.inner.lock().expect("timing lock");
|
||||
g.to_report(top_n)
|
||||
}
|
||||
|
||||
/// Record a phase duration directly in nanoseconds.
|
||||
///
|
||||
/// This is useful when aggregating sub-phase timings locally (to reduce lock contention)
|
||||
@@ -88,6 +93,22 @@ impl TimingHandle {
|
||||
g.phases.record(phase, nanos);
|
||||
}
|
||||
|
||||
pub fn record_publication_point_nanos(&self, manifest_rsync_uri: &str, nanos: u64) {
|
||||
let mut g = self.inner.lock().expect("timing lock");
|
||||
g.publication_points.record(manifest_rsync_uri, nanos);
|
||||
}
|
||||
|
||||
pub fn record_publication_point_step_nanos(
|
||||
&self,
|
||||
manifest_rsync_uri: &str,
|
||||
step: &'static str,
|
||||
nanos: u64,
|
||||
) {
|
||||
let mut g = self.inner.lock().expect("timing lock");
|
||||
g.publication_point_steps
|
||||
.record(&format!("{manifest_rsync_uri}::{step}"), nanos);
|
||||
}
|
||||
|
||||
pub fn write_json(&self, path: &Path, top_n: usize) -> Result<(), String> {
|
||||
let report = {
|
||||
let g = self.inner.lock().expect("timing lock");
|
||||
@@ -153,7 +174,7 @@ enum TimingSpanKind<'a> {
|
||||
PublicationPoint(&'a str),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct DurationStats {
|
||||
pub count: u64,
|
||||
pub total_nanos: u64,
|
||||
@@ -199,6 +220,7 @@ struct TimingCollector {
|
||||
rrdp_repos: DurationStatsMap,
|
||||
rrdp_repo_steps: DurationStatsMap,
|
||||
publication_points: DurationStatsMap,
|
||||
publication_point_steps: DurationStatsMap,
|
||||
}
|
||||
|
||||
impl TimingCollector {
|
||||
@@ -210,6 +232,7 @@ impl TimingCollector {
|
||||
rrdp_repos: DurationStatsMap::default(),
|
||||
rrdp_repo_steps: DurationStatsMap::default(),
|
||||
publication_points: DurationStatsMap::default(),
|
||||
publication_point_steps: DurationStatsMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +254,7 @@ impl TimingCollector {
|
||||
top_rrdp_repos: self.rrdp_repos.top(top_n),
|
||||
top_rrdp_repo_steps: self.rrdp_repo_steps.top(top_n),
|
||||
top_publication_points: self.publication_points.top(top_n),
|
||||
top_publication_point_steps: self.publication_point_steps.top(top_n),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,9 +268,10 @@ pub struct TimingReportV1 {
|
||||
pub top_rrdp_repos: Vec<TopDurationEntry>,
|
||||
pub top_rrdp_repo_steps: Vec<TopDurationEntry>,
|
||||
pub top_publication_points: Vec<TopDurationEntry>,
|
||||
pub top_publication_point_steps: Vec<TopDurationEntry>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct TopDurationEntry {
|
||||
pub key: String,
|
||||
pub count: u64,
|
||||
@@ -283,6 +308,12 @@ mod tests {
|
||||
let _pp = h.span_publication_point("rsync://example.test/repo/manifest.mft");
|
||||
}
|
||||
h.record_count("vrps", 42);
|
||||
h.record_publication_point_nanos("rsync://example.test/repo/manifest.mft", 1_000_000);
|
||||
h.record_publication_point_step_nanos(
|
||||
"rsync://example.test/repo/manifest.mft",
|
||||
"fresh_snapshot_prepare",
|
||||
1_000_000,
|
||||
);
|
||||
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let path = dir.path().join("timing.json");
|
||||
@@ -312,5 +343,11 @@ mod tests {
|
||||
.any(|e| e.key.contains("manifest.mft")),
|
||||
"expected PP in top list"
|
||||
);
|
||||
assert!(
|
||||
rep.top_publication_point_steps
|
||||
.iter()
|
||||
.any(|e| e.key.contains("fresh_snapshot_prepare")),
|
||||
"expected PP step in top list"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user