Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: update context to match spec #807

Merged
merged 11 commits into from Jun 23, 2021
Merged

fix: update context to match spec #807

merged 11 commits into from Jun 23, 2021

Conversation

robertlaurin
Copy link
Contributor

@robertlaurin robertlaurin commented Jun 9, 2021

# Returns the previous context so that it can be restored
#
# @param [Context] context The new context
# @return [Context] prev The previous context
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec refers to this as a "Token" rather than necessarily being the previous Context. Is there value in giving ourselves that flexibility or do we not need it?

Suggested change
# @return [Context] prev The previous context
# @return [Context] The previous context

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll admit I find the returning of a Token a bit unclear in the context of the detach documentation.

This operation is intended to help making sure the correct Context is associated with the caller's current execution unit. Users can rely on it to identify a wrong call order, i.e. trying to detach a Context that is not the current instance. In this case the operation can emit a signal to warn users of the wrong call order, such as logging an error or returning an error value.

The API MUST accept the following parameters:

A Token that was returned by a previous call to attach a Context.

What purpose does this token serve if we want to keep attaching and detaching balanced. Is there a situation where you want to detach and provide a token that doesn't match the current context?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a situation where you want to detach and provide a token that doesn't match the current context?

It helps double-check that attach and detach are balanced. These functions are meant to be low-level building blocks for higher level block-structured mechanisms. Passing an opaque Token around provides implementation flexibility while also being able to check for correct use of the functions, and report meaningful errors (oh yeah, we should do that 😄 ).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, why a Token instead of the Context? If we were to use an array as the Context stack instead of chaining contexts together internally, we'd likely use the array index as the Token instead of the Context itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so that makes it a lot clearer, I was under the impression that the token was to be used to actually retrieve a specific context instead of a means to assert that the attach/detach calls were lined up.

I think with the fact that should allow for attaching the same context multiple times it makes sense to use an array to keep track of the context stack, and to provide the array index as token to check against.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes based on discussion here 0c57bd6

Comment on lines 55 to 56
def detach(token = nil)
OpenTelemetry.logger.warn 'Calls to detach should match corresponding calls to attach' if token && token != stack.size
Copy link
Contributor

@fbogsany fbogsany Jun 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def detach(token = nil)
OpenTelemetry.logger.warn 'Calls to detach should match corresponding calls to attach' if token && token != stack.size
def detach(token)
calls_matched = (token == stack.size)
OpenTelemetry.logger.warn 'Calls to detach should match corresponding calls to attach' unless calls_matched

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, do you think there's value in logging the stack at this point, or at least the caller?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually thinking that it might be useful to define an exception for this situation and then have the error handler manage it. That way an application owner/instrumentation author can adjust the handling of the error based on their current needs.

def detach(token = nil)
OpenTelemetry.logger.warn 'Calls to detach should match corresponding calls to attach' if token && token != stack.size

previous_context = stack.pop || ROOT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the || ROOT implies the calls were mismatched - we should probably incorporate that into the calls_matched check (if the stack is empty, the calls must not have been matched).

@fbogsany fbogsany added the spec-compliance Required for OpenTelemetry spec compliance label Jun 15, 2021
@fbogsany fbogsany added this to the Tracing v1.0 milestone Jun 15, 2021
@robertlaurin robertlaurin merged commit bef61b5 into main Jun 23, 2021
@robertlaurin robertlaurin deleted the fix-context-to-spec branch June 23, 2021 21:44
ivoanjo added a commit to DataDog/dd-trace-rb that referenced this pull request Jun 25, 2021
In particular open-telemetry/opentelemetry-ruby#807
changed some of the APIs we were using to get the current span for a
thread.

To test both 0.17.0 and this new version I moved
opentelemetry to appraisals.
ivoanjo added a commit to DataDog/opentelemetry-ruby that referenced this pull request Jun 25, 2021
I've been working on integrating Datadog's continuous profiler with
opentelemetry traces (see DataDog/dd-trace-rb#1568).

The profiler runs on a background thread, and needs to be able to
access the current context for a thread, to be able to get the
current span's trace id and span ids (if any active).

To do so, I was originally using

```ruby
thread = ...
::OpenTelemetry::Trace.current_span(thread[::OpenTelemetry::Context::KEY])
```

Unfortunately, after open-telemetry#807, this interface was changed, and more
importantly, `Context::KEY` was removed and replaced with
`Context::STACK_KEY`. `STACK_KEY` was marked as `private_constant`.

With 1.0.0.rc2, the only way of getting this information is by
relying on private implementation details, which isn't great.

Thus, I would like to ask if it'd be reasonable to add an optional
`thread` parameter to `Context.current`. This would make it easy to
access the needed information, and it would even be more future-proof
as the outside code doesn't need to care anymore where and how
the context is stored.
ivoanjo added a commit to DataDog/opentelemetry-ruby that referenced this pull request Jun 25, 2021
I've been working on integrating Datadog's continuous profiler with
opentelemetry traces (see DataDog/dd-trace-rb#1568).

The profiler runs on a background thread, and needs to be able to
access the current context for a thread, to be able to get the
current span's trace id and span ids (if any active).

To do so, I was originally using

```ruby
thread = ...
::OpenTelemetry::Trace.current_span(thread[::OpenTelemetry::Context::KEY])
```

Unfortunately, after open-telemetry#807, this interface was changed, and more
importantly, `Context::KEY` was removed and replaced with
`Context::STACK_KEY`. `STACK_KEY` was marked as `private_constant`.

With 1.0.0.rc2, the only way of getting this information is by
relying on private implementation details, which isn't great.

Thus, I would like to ask if it'd be reasonable to add an optional
`thread` parameter to `Context.current`. This would make it easy to
access the needed information, and it would even be more future-proof
as the outside code doesn't need to care anymore where and how
the context is stored.
ivoanjo added a commit to DataDog/dd-trace-rb that referenced this pull request Jun 28, 2021
In particular open-telemetry/opentelemetry-ruby#807
changed some of the APIs we were using to get the current span for a
thread.

To test both 0.17.0 and this new version I moved
opentelemetry to appraisals.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spec-compliance Required for OpenTelemetry spec compliance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants