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

[WIP] Context API #99

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7867296
demo context header
satac2 Jun 8, 2020
d5a360a
demo context header
satac2 Jun 8, 2020
5d3b713
added file threadlocal_context.h
satac2 Jun 8, 2020
d047ff7
added fixes
satac2 Jun 8, 2020
f283cc6
Fixed syntatical errors, moved token class definition to context.h an…
satac2 Jun 8, 2020
e1de13f
Update api/include/opentelemetry/context/context.h
satac2 Jun 8, 2020
d5b155d
changed define guards and minor syntactical changes
satac2 Jun 8, 2020
80b2332
removing context vars class
satac2 Jun 8, 2020
64cd1c2
Merge branch 'context_api' of github.com:satac2/opentelemetry-cpp int…
satac2 Jun 8, 2020
4d24115
removed threadlocal context and made the runtime context methods static
satac2 Jun 8, 2020
a17c028
removed threadlocal context and made the runtime context methods static
satac2 Jun 8, 2020
d2df2ac
added a constructor
satac2 Jun 8, 2020
c316636
fixed convention issue and removed unnecessary code
satac2 Jun 8, 2020
7b36945
Update context.h
satac2 Jun 8, 2020
8e02c07
Update context.h
satac2 Jun 8, 2020
115cd68
context implementation
satac2 Jun 10, 2020
0d9fea1
Adding tests
satac2 Jun 10, 2020
565c40e
Adding tests
satac2 Jun 10, 2020
2d4a411
renamed some variables, added tests
satac2 Jun 10, 2020
9874c4c
renamed some variables, added tests
satac2 Jun 10, 2020
7bceaab
Merge branch 'context_api' into context_api_content
satac2 Jun 10, 2020
4b9fc2b
Merge pull request #5 from satac2/context_api_content
satac2 Jun 10, 2020
061e564
reversed public/private order
satac2 Jun 10, 2020
b5c81ad
Merge branch 'context_api_content' of github.com:satac2/opentelemetry…
satac2 Jun 10, 2020
b2717b3
Added detach test
satac2 Jun 10, 2020
ea687a9
Merge pull request #6 from satac2/context_api_content
satac2 Jun 10, 2020
b7259cd
avoiding standard datastructures
satac2 Jun 11, 2020
34eacf2
replaced std::map and created a thread_local context
satac2 Jun 17, 2020
a086993
replaced std::map and created a thread_local context
satac2 Jun 17, 2020
e44e926
cleaned up
satac2 Jun 17, 2020
6edce29
cleaned up
satac2 Jun 17, 2020
dff6f8f
fixed undefined behavior in context.h
satac2 Jun 20, 2020
e660ab7
minor style
satac2 Jun 21, 2020
aec8ca8
style
satac2 Jun 21, 2020
605cb75
added tests and comparison operator to the context api
satac2 Jun 22, 2020
e4d3069
auto formatted
satac2 Jun 22, 2020
4ad6395
Merge pull request #7 from satac2/context_api_content
satac2 Jun 22, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
168 changes: 168 additions & 0 deletions api/include/opentelemetry/context/context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#pragma once

#include <atomic>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>

#include "opentelemetry/common/attribute_value.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/utility.h"
#include "opentelemetry/nostd/variant.h"
#include "opentelemetry/trace/key_value_iterable.h"
#include "opentelemetry/trace/key_value_iterable_view.h"
#include "opentelemetry/trace/tracer.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace context
{

/* The context class provides a context identifier */
template <class T>
class Context
{

public:
/*The Key class is used to obscure access from the
* user to the context map. The identifier is used as a key
* to the context map.
*/
class Key
{

public:
/*Returns the key's identifier*/
nostd::string_view GetIdentifier() { return nostd::string_view(identifier_); }
/*Returns the key's name */
nostd::string_view GetName() { return key_name_; }

private:
friend class Context;

/* Constructs a new Key with the passed in name. Sets the identifier as
* the address of this object. */
Key(nostd::string_view key_name) : key_name_{key_name}
{
std::stringstream ss;
ss << (void *)this;
nostd::string_view temp_view;
temp_view = ss.str();

memcpy(identifier_, temp_view.data(), temp_view.size());
}

Copy link
Member

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.

nostd::string_view key_name_;

char identifier_[50];
};

/* Creates a key with the passed in name and returns it. */
Key CreateKey(nostd::string_view key_name) { return Key(key_name); }

/* Contructor, creates a context object from a map of keys
* and identifiers.
*/
Context(const T &attributes) : key_vals_(attributes)
{
/* Currently only used as a check, to ensure T is of the right type. */
trace::KeyValueIterableView<T> iterable = trace::KeyValueIterableView<T>(attributes);
}

Context() {}

/* Accepts a new iterable and then returns a new context that
* contains both the original pairs and the new pair.
*/
Context WriteValues(T &attributes) noexcept
{
/* Currently only used as a check, to ensure T is of the right type. */
trace::KeyValueIterableView<T> iterable = trace::KeyValueIterableView<T>(attributes);

std::insert_iterator<T> back(attributes, std::begin(attributes));

for (auto iter = std::begin(key_vals_); iter != std::end(key_vals_); ++iter)
{
back = *iter;
}

return Context(attributes);
}

/* Returns the value associated with the passed in key */
common::AttributeValue GetValue(Key key)
{

for (auto iter = std::begin(key_vals_); iter != std::end(key_vals_); ++iter)
{
if (key.GetIdentifier() == iter->first)
{
return iter->second;
}
}

return "";
}

/* Iterates through the current and comparing context objects
* to check for equality, */
bool operator==(const Context &other)
{

/*Check for case where either both or one object has no contents. */
if (std::begin(other.key_vals_) == std::end(other.key_vals_))
{
if (std::begin(key_vals_) == std::end(key_vals_))
{
return true;
}
else
{
return false;
}
}

if (std::begin(key_vals_) == std::end(key_vals_))
{
return false;
}

/*Compare the contexts*/
for (auto iter = std::begin(key_vals_); iter != std::end(key_vals_); ++iter)
{
int found = 0;

for (auto iter_other = std::begin(other.key_vals_); iter_other != std::end(other.key_vals_);
iter_other++)
{
if (iter->first == iter_other->first)
{
if (nostd::get<nostd::string_view>(iter->second) ==
nostd::get<nostd::string_view>(iter_other->second))
{
found = 1;
break;
}
}
}

if (found == 0)
{
return false;
}
}

return true;
}

/* Copy Constructors. */
Context(const Context &other) = default;
Context &operator=(const Context &other) = default;

private:
T key_vals_;
};

} // namespace context
OPENTELEMETRY_END_NAMESPACE
50 changes: 50 additions & 0 deletions api/include/opentelemetry/context/runtime_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once

#include "context.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace context
{

/* The RuntimeContext class provides a wrapper for
* propogating context through cpp. */
template <class M>
class RuntimeContext
{
public:
/* The token class provides an identifier that is used by
* the attach and detach methods to keep track of context
* objects.
*/
class Token
{
private:
friend class RuntimeContext<M>;

Context<M> context_;

/* A constructor that sets the token's Context object to the
* one that was passed in.
*/
Token(Context<M> &context) { context_ = context; }

/* Returns the stored context object. */
Context<M> GetContext() { return context_; }
};

/* Return the current context. */
Context<M> GetCurrent();

/* Sets the current 'Context' object. Returns a token
* that can be used to reset to the previous Context.
*/

Token Attach(Context<M> &context);

/* Resets the context to a previous value stored in the
* passed in token. Returns zero if successful, -1 otherwise
*/
int Detach(Token &token);
};
} // namespace context
OPENTELEMETRY_END_NAMESPACE
73 changes: 73 additions & 0 deletions api/include/opentelemetry/context/threadlocal_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#pragma once

#include "opentelemetry/context/runtime_context.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace context
{
/* The ThreadLocalContext class is a derived class from RuntimeContext and
* provides a wrapper for
* propogating context through cpp thread locally. */
template <class M>
class ThreadLocalContext : public RuntimeContext<M>
{
public:
/* The token class provides an identifier that is used by
* the attach and detach methods to keep track of context
* objects.
*/
class Token
{
private:
friend class ThreadLocalContext<M>;

Context<M> context_;

/* A constructor that sets the token's Context object to the
* one that was passed in.
*/
Token(Context<M> &context) { context_ = context; }

/* Returns the stored context object. */
Context<M> GetContext() { return context_; }
};

/* Return the current context. */
static Context<M> GetCurrent() { return GetInstance(); }

/* Resets the context to a previous value stored in the
* passed in token. Returns zero if successful, -1 otherwise
*/
static int Detach(Token &token)
{

/* If the token context is the current context, return failure. */
if (token.GetContext() == GetCurrent())
{
return 1;
}

GetInstance() = token.GetContext();
return 0;
}

/* Sets the current 'Context' object. Returns a token
* that can be used to reset to the previous Context.
*/
static Token Attach(Context<M> &context)
{
Token old_context = Token(GetInstance());
GetInstance() = context;
return old_context;
}

private:
/* Provides storage and access to the thread_local context object */
static Context<M> &GetInstance()
{
static thread_local Context<M> instance;
return instance;
}
};
} // namespace context
OPENTELEMETRY_END_NAMESPACE
1 change: 1 addition & 0 deletions api/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_subdirectory(core)
add_subdirectory(context)
add_subdirectory(plugin)
add_subdirectory(nostd)
add_subdirectory(trace)
23 changes: 23 additions & 0 deletions api/test/context/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
load("//bazel:otel_cc_benchmark.bzl", "otel_cc_benchmark")

cc_test(
name = "context_test",
srcs = [
"context_test.cc",
],
deps = [
"//api",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "thread_local_test",
srcs = [
"thread_local_test.cc",
],
deps = [
"//api",
"@com_google_googletest//:gtest_main",
],
)
Loading