-
Notifications
You must be signed in to change notification settings - Fork 410
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
[WIP] Context API #99
Conversation
…d added the contextvars_context.h file
Co-authored-by: Kirk Kelsey <kirkmkelsey@gmail.com>
/* Context: contructor, creates a context object from a map | ||
* of keys and identifiers | ||
*/ | ||
Context(std::map<std::string, int> ctx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the public APIs need to be ABI compatible - which means they are not supposed to expose dependency on STL traits/layout.
Welcome to your first PR @satac2, please clear the CLA steps as required by the CI / CNCF. |
Context api content
Context api content
|
||
context_id_mutex.lock(); | ||
|
||
Context::last_key_identifier_++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of maintaining a counter and introducing a contention, consider using the address of the underlying object to uniquely identify the key.
Context(std::map<int,int> ctx_map){ | ||
ctx_map_ = ctx_map; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to format the code.
/* Contructor, creates a context object from a map | ||
* of keys and identifiers | ||
*/ | ||
Context(ContextKey key, int value){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ctor would only take 1 key-value pair?
/* Accepts a new key/value pair and then returns a new | ||
* context that contains both the original pairs and the new pair. | ||
*/ | ||
Context WriteValue(ContextKey key, int value){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the value should a nostd::variant type instead of an int?
} | ||
|
||
/* A constructor that will set the context as the passed in context. */ | ||
RuntimeContext(Context &context){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the spec these will be global/static function so no ctor needed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My current thinking:
- Provide
RuntimeContext
as an interface, providing static methods for Attach/Detach/GetCurrent. - Implement
ThreadLocalContext
, providing biding for TLS (thread local storage). - By default the static methods from
RuntimeContext
will useThreadLocalContext
, and there is a way for the user to implement/specify their own context binding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused what you mean by this, should the ThreadLocalContext be a derived class of RuntimeContext?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused what you mean by this, should the ThreadLocalContext be a derived class of RuntimeContext?
Yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would it be different than RuntimeContext, should the RuntimeContext just have a static context and the ThreadLocal have a static thread_local context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think RuntimeContext is the abstraction layer (which doesn't have understanding about TLS).
/* Constructs a new ContextKey with the passed in name and | ||
* identifier. | ||
*/ | ||
ContextKey(std::string key_name, int identifier){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't use std::string , only nostd::string_view in API
/* Consructs a new ContextKey with the passed in name and increments | ||
* the identifier then assigns it to be the key's identifier. | ||
*/ | ||
ContextKey(std::string key_name){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use nostd::string_view
* user to the context map. The identifier is used as a key | ||
* to the context map. | ||
*/ | ||
class ContextKey{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest to use this class as a foundation for key-value iterable:
https://github.com/open-telemetry/opentelemetry-cpp/blob/master/api/include/opentelemetry/trace/key_value_iterable.h
You can entirely avoid using std::map in API. We do not require std::map
|
||
private: | ||
|
||
static thread_local Context context_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not 100% sure this static would always work in certain DLL loading scenarios, where two different DLLs consume OT API surface, esp. lazy loading / delay-loading. May want to spell out the limitations somewhere in the class documentation..
https://devblogs.microsoft.com/oldnewthing/20101122-00/?p=12233
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Rather use this singleton style (adding thread_local
). That's what we use here.
|
||
std::mutex context_id_mutex; | ||
|
||
/*The context class provides a context identifier */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use // style comments and add a full stop. :)
/* Consructs a new ContextKey with the passed in name and increments | ||
* the identifier then assigns it to be the key's identifier. | ||
*/ | ||
ContextKey(std::string key_name){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please mark this constructor explicit.
api/test/context/BUILD
Outdated
cc_test( | ||
name = "runtimeContext_test", | ||
srcs = [ | ||
"runtimeContext_test.cc", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use lowercase + underscores, i.e. runtime_context_test (also on L15) to be consistent with the rest of the files.
api/test/context/BUILD
Outdated
srcs = [ | ||
"runtimeContext_test.cc", | ||
], | ||
copts = ["-Wall","-std=c++17"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove these copts.
More general context questions:
|
|
And refcount the context objects that form chains? |
Can we have a no-op Context API and move the implementation into the SDK, so that other SDKs can make different performance tradeoffs in how this is implemented? |
Probably not, the OpenTelemetry API package has to give a default implementation that flows the incoming traceid/spanid/tracestate/flags to the outgoing request, thus the actual implementation cannot be in the SDK. |
Context api content
If you could take a look at the class declarations and see if I am on the right track for the context api, that would be great, thanks.