Skip to content

Commit a317856

Browse files
gruebelTommyCppcijothomas
authored
refactor: refactor Baggage with Context interaction (#2748)
Co-authored-by: Zhongyang Wu <[email protected]> Co-authored-by: Cijo Thomas <[email protected]>
1 parent baf4bfd commit a317856

File tree

3 files changed

+52
-37
lines changed

3 files changed

+52
-37
lines changed

opentelemetry-sdk/src/propagation/baggage.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn baggage_fields() -> &'static [String; 1] {
3030
/// # Examples
3131
///
3232
/// ```
33-
/// use opentelemetry::{baggage::BaggageExt, KeyValue, propagation::TextMapPropagator};
33+
/// use opentelemetry::{baggage::{Baggage, BaggageExt}, propagation::TextMapPropagator};
3434
/// use opentelemetry_sdk::propagation::BaggagePropagator;
3535
/// use std::collections::HashMap;
3636
///
@@ -48,14 +48,17 @@ fn baggage_fields() -> &'static [String; 1] {
4848
/// }
4949
///
5050
/// // Add new baggage
51-
/// let cx_with_additions = cx.with_baggage(vec![KeyValue::new("server_id", 42)]);
51+
/// let mut baggage = Baggage::new();
52+
/// let _ = baggage.insert("server_id", "42");
53+
///
54+
/// let cx_with_additions = cx.with_baggage(baggage);
5255
///
5356
/// // Inject baggage into http request
5457
/// propagator.inject_context(&cx_with_additions, &mut headers);
5558
///
5659
/// let header_value = headers.get("baggage").expect("header is injected");
57-
/// assert!(header_value.contains("user_id=1"), "still contains previous name-value");
58-
/// assert!(header_value.contains("server_id=42"), "contains new name-value pair");
60+
/// assert!(!header_value.contains("user_id=1"), "still contains previous name-value");
61+
/// assert!(header_value.contains("server_id=42"), "does not contain new name-value pair");
5962
/// ```
6063
///
6164
/// [W3C Baggage]: https://w3c.github.io/baggage
@@ -98,7 +101,7 @@ impl TextMapPropagator for BaggagePropagator {
98101
/// Extracts a `Context` with baggage values from a `Extractor`.
99102
fn extract_with_context(&self, cx: &Context, extractor: &dyn Extractor) -> Context {
100103
if let Some(header_value) = extractor.get(BAGGAGE_HEADER) {
101-
let baggage = header_value.split(',').flat_map(|context_value| {
104+
let baggage = header_value.split(',').filter_map(|context_value| {
102105
if let Some((name_and_value, props)) = context_value
103106
.split(';')
104107
.collect::<Vec<&str>>()

opentelemetry/CHANGELOG.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
- *Breaking* Moved `TraceResult` type alias from `opentelemetry::trace::TraceResult` to `opentelemetry_sdk::trace::TraceResult`
88
- {PLACEHOLDER} - Remove the above completely. // TODO fill this when changes are actually in.
99
- Bug Fix: `InstrumentationScope` implementation for `PartialEq` and `Hash` fixed to include Attributes also.
10-
- *Breaking* Changed value type of `Baggage` from `Value` to `StringValue`
11-
- Updated `Baggage` constants to reflect latest standard (`MAX_KEY_VALUE_PAIRS` - 180 -> 64, `MAX_BYTES_FOR_ONE_PAIR` - removed) and increased insert performance see #[2284](https://github.com/open-telemetry/opentelemetry-rust/pull/2284).
12-
- *Breaking* Align `Baggage.remove()` signature with `.get()` to take the key as a reference
10+
- **Breaking changes for baggage users**: [#2717](https://github.com/open-telemetry/opentelemetry-rust/issues/2717)
11+
- Changed value type of `Baggage` from `Value` to `StringValue`
12+
- Updated `Baggage` constants to reflect latest standard (`MAX_KEY_VALUE_PAIRS` - 180 -> 64, `MAX_BYTES_FOR_ONE_PAIR` - removed) and increased insert performance see #[2284](https://github.com/open-telemetry/opentelemetry-rust/pull/2284).
13+
- Align `Baggage.remove()` signature with `.get()` to take the key as a reference
14+
- `Baggage` can't be retrieved from the `Context` directly anymore and needs to be accessed via `context.baggage()`
15+
- `with_baggage()` and `current_with_baggage()` override any existing `Baggage` in the `Context`
1316
- Changed `Context` to use a stack to properly handle out of order dropping of `ContextGuard`. This imposes a limit of `65535` nested contexts on a single thread. See #[2378](https://github.com/open-telemetry/opentelemetry-rust/pull/2284) and #[1887](https://github.com/open-telemetry/opentelemetry-rust/issues/1887).
14-
1517
- Added additional `name: Option<&str>` parameter to the `event_enabled` method
1618
on the `Logger` trait. This allows implementations (SDK, processor, exporters)
1719
to leverage this additional information to determine if an event is enabled.

opentelemetry/src/baggage.rs

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,16 @@ impl FromIterator<KeyValueMetadata> for Baggage {
273273
}
274274
}
275275

276+
impl<I> From<I> for Baggage
277+
where
278+
I: IntoIterator,
279+
I::Item: Into<KeyValueMetadata>,
280+
{
281+
fn from(value: I) -> Self {
282+
value.into_iter().map(Into::into).collect()
283+
}
284+
}
285+
276286
fn encode(s: &str) -> String {
277287
let mut encoded_string = String::with_capacity(s.len());
278288

@@ -312,39 +322,46 @@ pub trait BaggageExt {
312322
/// # Examples
313323
///
314324
/// ```
315-
/// use opentelemetry::{baggage::BaggageExt, Context, KeyValue, StringValue};
325+
/// use opentelemetry::{baggage::{Baggage, BaggageExt}, Context, KeyValue, StringValue};
326+
///
327+
/// // Explicit `Baggage` creation
328+
/// let mut baggage = Baggage::new();
329+
/// let _ = baggage.insert("my-name", "my-value");
330+
///
331+
/// let cx = Context::map_current(|cx| {
332+
/// cx.with_baggage(baggage)
333+
/// });
316334
///
335+
/// // Passing an iterator
317336
/// let cx = Context::map_current(|cx| {
318-
/// cx.with_baggage(vec![KeyValue::new("my-name", "my-value")])
337+
/// cx.with_baggage([KeyValue::new("my-name", "my-value")])
319338
/// });
320339
///
321340
/// assert_eq!(
322341
/// cx.baggage().get("my-name"),
323342
/// Some(&StringValue::from("my-value")),
324343
/// )
325344
/// ```
326-
fn with_baggage<T: IntoIterator<Item = I>, I: Into<KeyValueMetadata>>(
327-
&self,
328-
baggage: T,
329-
) -> Self;
345+
fn with_baggage<T: Into<Baggage>>(&self, baggage: T) -> Self;
330346

331347
/// Returns a clone of the current context with the included name/value pairs.
332348
///
333349
/// # Examples
334350
///
335351
/// ```
336-
/// use opentelemetry::{baggage::BaggageExt, Context, KeyValue, StringValue};
352+
/// use opentelemetry::{baggage::{Baggage, BaggageExt}, Context, StringValue};
337353
///
338-
/// let cx = Context::current_with_baggage(vec![KeyValue::new("my-name", "my-value")]);
354+
/// let mut baggage = Baggage::new();
355+
/// let _ = baggage.insert("my-name", "my-value");
356+
///
357+
/// let cx = Context::current_with_baggage(baggage);
339358
///
340359
/// assert_eq!(
341360
/// cx.baggage().get("my-name"),
342361
/// Some(&StringValue::from("my-value")),
343362
/// )
344363
/// ```
345-
fn current_with_baggage<T: IntoIterator<Item = I>, I: Into<KeyValueMetadata>>(
346-
baggage: T,
347-
) -> Self;
364+
fn current_with_baggage<T: Into<Baggage>>(baggage: T) -> Self;
348365

349366
/// Returns a clone of the given context with no baggage.
350367
///
@@ -364,33 +381,26 @@ pub trait BaggageExt {
364381
fn baggage(&self) -> &Baggage;
365382
}
366383

367-
impl BaggageExt for Context {
368-
fn with_baggage<T: IntoIterator<Item = I>, I: Into<KeyValueMetadata>>(
369-
&self,
370-
baggage: T,
371-
) -> Self {
372-
let old = self.baggage();
373-
let mut merged = Baggage {
374-
inner: old.inner.clone(),
375-
kv_content_len: old.kv_content_len,
376-
};
377-
for kvm in baggage.into_iter().map(|kv| kv.into()) {
378-
merged.insert_with_metadata(kvm.key, kvm.value, kvm.metadata);
379-
}
384+
/// Solely used to store `Baggage` in the `Context` without allowing direct access
385+
#[derive(Debug)]
386+
struct BaggageContextValue(Baggage);
380387

381-
self.with_value(merged)
388+
impl BaggageExt for Context {
389+
fn with_baggage<T: Into<Baggage>>(&self, baggage: T) -> Self {
390+
self.with_value(BaggageContextValue(baggage.into()))
382391
}
383392

384-
fn current_with_baggage<T: IntoIterator<Item = I>, I: Into<KeyValueMetadata>>(kvs: T) -> Self {
385-
Context::map_current(|cx| cx.with_baggage(kvs))
393+
fn current_with_baggage<T: Into<Baggage>>(baggage: T) -> Self {
394+
Context::map_current(|cx| cx.with_baggage(baggage))
386395
}
387396

388397
fn with_cleared_baggage(&self) -> Self {
389398
self.with_value(Baggage::new())
390399
}
391400

392401
fn baggage(&self) -> &Baggage {
393-
self.get::<Baggage>().unwrap_or(get_default_baggage())
402+
self.get::<BaggageContextValue>()
403+
.map_or(get_default_baggage(), |b| &b.0)
394404
}
395405
}
396406

0 commit comments

Comments
 (0)