perf(ecstore): cache io_uring fallback root label (#4747)

`record_uring_fallback` is called at multiple sites in the io_uring read
path whenever a read falls back to `StdBackend`. It formatted
`self.root.display().to_string()` on every call, heap-allocating a
`String` from a `Path` that never changes after construction — pure
per-read waste when io_uring is degraded.

Cache the label once in `UringBackend::try_new` as a `String` field
(`root_label`) and clone it per emission. The metric name and the
`"root"` label value are unchanged; only the redundant `Path` formatting
is removed. The clone is a single alloc of an already-short string.

Refs: rustfs/backlog#1185

Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
houseme
2026-07-12 01:25:06 +08:00
committed by GitHub
parent 5282c71f86
commit 89557a7ffe
+11 -1
View File
@@ -2935,6 +2935,10 @@ impl FdCache {
#[cfg(target_os = "linux")]
pub(crate) struct UringBackend {
root: PathBuf,
/// Caches `root.display().to_string()` for the metric `"root"` label. `root`
/// never changes after construction, so formatting the `Path` on every
/// fallback emission is pure waste (rustfs/backlog#1185).
root_label: String,
inner: StdBackend,
/// Wrapped in `ManuallyDrop` so `Drop` can move the (last) `Arc` onto a
/// blocking thread: `UringDriver`'s own `Drop` joins its driver threads and
@@ -3086,9 +3090,13 @@ impl UringBackend {
// Periodically export the driver StatsSnapshot to metrics so a
// gray release is not flying blind (rustfs/backlog#1172).
Self::spawn_stats_exporter(&driver, root.clone());
// Compute the metric label once, before `root` moves into the
// struct (rustfs/backlog#1185).
let root_label = root.display().to_string();
Some(Self {
inner: StdBackend::new(root.clone()),
root,
root_label,
driver: std::mem::ManuallyDrop::new(driver),
active: std::sync::atomic::AtomicBool::new(true),
fallback_logged: std::sync::atomic::AtomicBool::new(false),
@@ -3153,7 +3161,9 @@ impl UringBackend {
/// how much traffic is actually on io_uring vs falling back
/// (rustfs/backlog#1172).
fn record_uring_fallback(&self) {
counter!(METRIC_URING_FALLBACK_TOTAL, "root" => self.root.display().to_string()).increment(1);
// Clone the cached label (one alloc of a short string) instead of
// re-formatting the `Path` per read (rustfs/backlog#1185).
counter!(METRIC_URING_FALLBACK_TOTAL, "root" => self.root_label.clone()).increment(1);
}
/// Spawn a low-frequency task that exports the per-disk driver StatsSnapshot