Skip to content

Commit fbce18a

Browse files
perf(fetch): avoid allocations in client_scope for borrowed-'static names (#514)
`client_scope` previously called `to_string()` on the runtime and transport names, forcing a heap allocation on every client build even though the transport already stores these names as `Cow<'static, str>`. `client_scope` now takes `impl Into<Value>` for the runtime and transport names — the exact bound `KeyValue::new` requires — and hands each value straight into the instrumentation scope attributes with no extra clone inside the function. The production call sites in `client_builder.rs` pass `transport.runtime().clone()`/`transport.name().clone()`; cloning the transport's `Cow<'static, str>` is allocation-free for the common borrowed-`'static` case and simply hands over ownership. The in-file unit tests pass plain `&'static str` literals, which likewise convert into `Value` without allocating. Net effect: borrowed-`'static` runtime/transport names no longer allocate when building the meter scope, and the signature stays idiomatic (no `clippy::ptr_arg` `#[expect]` or `&Cow` borrow needed). Verified with `just package=fetch clippy` (clean) and `just package=fetch test` (153 passed). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 828ced2 commit fbce18a

2 files changed

Lines changed: 8 additions & 5 deletions

File tree

crates/fetch/src/client_builder.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl HttpClientBuilder {
5656
Self {
5757
options: ClientOptions::default(),
5858
pipeline_builder: PipelineBuilder::default(),
59-
metering: Metering::global(client_scope(transport.runtime(), transport.name())),
59+
metering: Metering::global(client_scope(transport.runtime().clone(), transport.name().clone())),
6060
transport,
6161
resilience_context: HttpResilienceContext::new(&clock).name(DEFAULT_HTTP_CLIENT_NAME).use_logs(),
6262
}
@@ -241,7 +241,10 @@ impl HttpClientBuilder {
241241
pub fn meter_provider(self, meter_provider: &dyn MeterProvider) -> Self {
242242
// Update the metering at all relevant places
243243
Self {
244-
metering: Metering::custom(meter_provider, client_scope(self.transport.runtime(), self.transport.name())),
244+
metering: Metering::custom(
245+
meter_provider,
246+
client_scope(self.transport.runtime().clone(), self.transport.name().clone()),
247+
),
245248
resilience_context: self.resilience_context.use_metrics(meter_provider),
246249
..self
247250
}

crates/fetch/src/telemetry.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ impl From<Metering> for Meter {
9898

9999
/// Builds the `fetch` instrumentation scope carrying the `fetch.runtime` and
100100
/// `fetch.transport` attributes, attached to every metric a client records.
101-
pub(crate) fn client_scope(runtime: &str, transport: &str) -> InstrumentationScope {
101+
pub(crate) fn client_scope(runtime: impl Into<Value>, transport: impl Into<Value>) -> InstrumentationScope {
102102
InstrumentationScope::builder(METER_NAME)
103103
.with_attributes([
104-
KeyValue::new(FETCH_RUNTIME_ATTRIBUTE, runtime.to_string()),
105-
KeyValue::new(FETCH_TRANSPORT_ATTRIBUTE, transport.to_string()),
104+
KeyValue::new(FETCH_RUNTIME_ATTRIBUTE, runtime),
105+
KeyValue::new(FETCH_TRANSPORT_ATTRIBUTE, transport),
106106
])
107107
.build()
108108
}

0 commit comments

Comments
 (0)