Skip to content

Commit

Permalink
Allow root Context to be overridden (#3230)
Browse files Browse the repository at this point in the history
* Allow root Context to be overridden

Adds ContextStorage.root() to provide a way to customize the
implementation of the root Context when you don't want the
root to be an ArrayBasedContext.

* Update context/src/main/java/io/opentelemetry/context/ContextStorage.java

Co-authored-by: Anuraag Agrawal <[email protected]>
Co-authored-by: Anuraag Agrawal <[email protected]>
  • Loading branch information
3 people authored Jul 21, 2021
1 parent d4bbaf4 commit 0d2b7b0
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ static Context current() {
* is only a workaround hiding an underlying context propagation issue.
*/
static Context root() {
return ArrayBasedContext.root();
return ContextStorage.get().root();
}

/**
Expand Down
10 changes: 10 additions & 0 deletions context/src/main/java/io/opentelemetry/context/ContextStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,14 @@ static void addWrapper(Function<? super ContextStorage, ? extends ContextStorage
*/
@Nullable
Context current();

/**
* Returns the root {@link Context} which all other {@link Context} are derived from.
*
* <p>The default implementation returns the root {@code ArrayBasedContext}, but subclasses can
* override this method to return a root instance of a different {@link Context} implementation.
*/
default Context root() {
return ArrayBasedContext.root();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ public Context current() {
if (current != null) {
return new BraveContextWrapper(current);
}
return new BraveContextWrapper(TraceContext.newBuilder().traceId(1).spanId(1).build());
return root();
}

@Override
public Context root() {
return BraveContextWrapper.ROOT;
}
}

Expand Down Expand Up @@ -86,6 +91,9 @@ BraveContextValues with(Object key, Object value) {

private static class BraveContextWrapper implements Context {

private static final BraveContextWrapper ROOT =
new BraveContextWrapper(TraceContext.newBuilder().traceId(1).spanId(1).build());

private final TraceContext braveContext;

private BraveContextWrapper(TraceContext braveContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,18 @@ public Scope attach(Context toAttach) {
public Context current() {
return new BraveContextWrapper(Tracing.current().currentTraceContext().get());
}

@Override
public Context root() {
return BraveContextWrapper.ROOT;
}
}

// Need to wrap the Context because brave findExtra searches for perfect match of the class.
static final class BraveContextWrapper implements Context {

static final BraveContextWrapper ROOT = new BraveContextWrapper(null, ArrayBasedContext.root());

@Nullable private final TraceContext baseBraveContext;
private final Context delegate;

Expand Down Expand Up @@ -93,7 +101,7 @@ static TraceContext toBraveContext(@Nullable TraceContext braveContext, Context

private static Context fromBraveContext(@Nullable TraceContext braveContext) {
if (braveContext == null) {
return Context.root();
return BraveContextWrapper.ROOT.delegate;
}
List<Object> extra = braveContext.extra();
for (int i = extra.size() - 1; i >= 0; i--) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

public class GrpcContextStorageProvider implements ContextStorageProvider {
private static final io.grpc.Context.Key<Context> OTEL_CONTEXT =
io.grpc.Context.keyWithDefault("otel-context", Context.root());
io.grpc.Context.keyWithDefault("otel-context", GrpcContextWrapper.ROOT.context);

@Override
public ContextStorage get() {
Expand Down Expand Up @@ -44,9 +44,18 @@ public Context current() {
io.grpc.Context grpcContext = io.grpc.Context.current();
return GrpcContextWrapper.wrapperFromGrpc(grpcContext);
}

@Override
public Context root() {
return GrpcContextWrapper.ROOT;
}
}

private static class GrpcContextWrapper implements Context {

private static final GrpcContextWrapper ROOT =
new GrpcContextWrapper(io.grpc.Context.ROOT, ArrayBasedContext.root());

// If otel context changes the grpc Context may be out of sync.
// There are 2 options here: 1. always update the grpc Context, 2. update only when needed.
// Currently the second one is implemented.
Expand Down
4 changes: 3 additions & 1 deletion docs/apidiffs/current_vs_latest/opentelemetry-context.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Comparing source compatibility of against
No changes.
***! MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.context.ContextStorage (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.context.Context root()

0 comments on commit 0d2b7b0

Please sign in to comment.