Skip to content

Commit 476b7d5

Browse files
committed
allow retrieval of Context from ContextGuard
1 parent 24b92cb commit 476b7d5

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

opentelemetry/src/context.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,11 @@ impl Context {
324324
/// assert_eq!(Context::current().get::<ValueA>(), None);
325325
/// ```
326326
pub fn attach(self) -> ContextGuard {
327-
let cx_id = CURRENT_CONTEXT.with(|cx| cx.borrow_mut().push(self));
327+
let cx_id = CURRENT_CONTEXT.with(|cx| cx.borrow_mut().push(self.clone()));
328328

329329
ContextGuard {
330330
cx_pos: cx_id,
331+
context: self,
331332
_marker: PhantomData,
332333
}
333334
}
@@ -456,10 +457,19 @@ impl fmt::Debug for Context {
456457
pub struct ContextGuard {
457458
// The position of the context in the stack. This is used to pop the context.
458459
cx_pos: u16,
460+
// The current context.
461+
context: Context,
459462
// Ensure this type is !Send as it relies on thread locals
460463
_marker: PhantomData<*const ()>,
461464
}
462465

466+
impl ContextGuard {
467+
/// Retrieve the Context
468+
pub fn context(&self) -> &Context {
469+
&self.context
470+
}
471+
}
472+
463473
impl Drop for ContextGuard {
464474
fn drop(&mut self) {
465475
let id = self.cx_pos;
@@ -997,6 +1007,33 @@ mod tests {
9971007
assert!(suppressed.is_telemetry_suppressed());
9981008
}
9991009

1010+
#[test]
1011+
fn test_retrieve_context_from_guard() {
1012+
let outer_guard = Context::new()
1013+
.with_value(ValueA(1))
1014+
.with_value(ValueB(2))
1015+
.attach();
1016+
1017+
assert_eq!(outer_guard.context().get::<ValueA>(), Some(&ValueA(1)));
1018+
assert_eq!(outer_guard.context().get::<ValueB>(), Some(&ValueB(2)));
1019+
1020+
{
1021+
let inner_guard = Context::current_with_value(ValueB(42)).attach();
1022+
// ValueB is changed in inner guard's context
1023+
assert_eq!(inner_guard.context().get(), Some(&ValueA(1)));
1024+
assert_eq!(inner_guard.context().get(), Some(&ValueB(42)));
1025+
1026+
assert!(Context::map_current(|cx| {
1027+
assert_eq!(cx.get(), Some(&ValueA(1)));
1028+
assert_eq!(cx.get(), Some(&ValueB(42)));
1029+
true
1030+
}));
1031+
1032+
// Outer guard's context still has original ValueB
1033+
assert_eq!(outer_guard.context().get::<ValueB>(), Some(&ValueB(2)));
1034+
}
1035+
}
1036+
10001037
#[test]
10011038
fn test_with_telemetry_suppressed() {
10021039
// Start with a normal context

0 commit comments

Comments
 (0)