Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
Merge pull request #37 from opentracing/bhs/immutable_context
Browse files Browse the repository at this point in the history
Move to the immutable SpanContext model
  • Loading branch information
bensigelman authored Aug 11, 2016
2 parents 4c480ec + aad6bca commit 24be419
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 57 deletions.
20 changes: 20 additions & 0 deletions opentracing-api/src/main/java/io/opentracing/Span.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,24 @@ public interface Span extends AutoCloseable {
* The timestamp in microseconds in UTC time.
**/
Span log(long timestampMicroseconds, String eventName, /* @Nullable */ Object payload);

/**
* Sets a baggage item in the Span (and its SpanContext) as a key/value pair.
*
* Baggage enables powerful distributed context propagation functionality where arbitrary application data can be
* carried along the full path of request execution throughout the system.
*
* Note 1: Baggage is only propagated to the future (recursive) children of this SpanContext.
*
* Note 2: Baggage is sent in-band with every subsequent local and remote calls, so this feature must be used with
* care.
*
* @return this Span instance, for chaining
*/
Span setBaggageItem(String key, String value);

/**
* @return the value of the baggage item identified by the given key, or null if no such item could be found
*/
String getBaggageItem(String key);
}
32 changes: 12 additions & 20 deletions opentracing-api/src/main/java/io/opentracing/SpanContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,24 @@
*/
package io.opentracing;

import java.util.Map;

/**
* SpanContext represents Span state that must propagate to descendant Spans and across process boundaries.
*
* SpanContext is logically divided into two pieces: (1) the user-level "Baggage" (see set_baggage_item and
* get_baggage_item) that propagates across Span boundaries and (2) any Tracer-implementation-specific fields that are
* needed to identify or otherwise contextualize the associated Span instance (e.g., a <trace_id, span_id, sampled>
* tuple).
* SpanContext is logically divided into two pieces: (1) the user-level "Baggage" that propagates across Span
* boundaries and (2) any Tracer-implementation-specific fields that are needed to identify or otherwise contextualize
* the associated Span instance (e.g., a <trace_id, span_id, sampled> tuple).
*
* @see Span#setBaggageItem(String, String)
* @see Span#getBaggageItem(String)
*/
public interface SpanContext {
/**
* Sets a baggage item in the SpanContext as a key/value pair.
*
* Baggage enables powerful distributed context propagation functionality where arbitrary application data can be
* carried along the full path of request execution throughout the system.
*
* Note 1: Baggage is only propagated to the future (recursive) children of this SpanContext.
* @return all zero or more baggage items propagating along with the associated Span
*
* Note 2: Baggage is sent in-band with every subsequent local and remote calls, so this feature must be used with
* care.
*
* @return this SpanContext instance, for chaining
*/
SpanContext setBaggageItem(String key, String value);

/**
* @return the value of the baggage item identified by the given key, or null if no such item could be found
* @see Span#setBaggageItem(String, String)
* @see Span#getBaggageItem(String)
*/
String getBaggageItem(String key);
Iterable<Map.Entry<String, String>> baggageItems();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@
*/
package io.opentracing;

import io.opentracing.References;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -88,7 +84,7 @@ public final Span start() {
stringTags.entrySet().stream().forEach((entry) -> { span.setTag(entry.getKey(), entry.getValue()); });
booleanTags.entrySet().stream().forEach((entry) -> { span.setTag(entry.getKey(), entry.getValue()); });
numberTags.entrySet().stream().forEach((entry) -> { span.setTag(entry.getKey(), entry.getValue()); });
baggage.entrySet().stream().forEach((entry) -> { span.context().setBaggageItem(entry.getKey(), entry.getValue()); });
baggage.entrySet().stream().forEach((entry) -> { span.setBaggageItem(entry.getKey(), entry.getValue()); });
return span;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,7 @@ public void testInject() {
AbstractTracer instance = new TestTracerImpl();
instance.register(TextMap.class, new TestTextMapInjectorImpl());

String operationName = "test-inject-span";
Span span = new AbstractSpan(operationName) {
SpanContext spanContext = new TestSpanContextImpl("whatever");

@Override
public SpanContext context() {
return spanContext;
}
};
Span span = new TestSpanImpl("test-inject-span");
Map<String,String> map = new HashMap<>();
TextMap carrier = new TextMapInjectAdapter(map);
instance.inject(span.context(), Format.Builtin.TEXT_MAP, carrier);
Expand Down Expand Up @@ -106,14 +98,7 @@ public AbstractSpanBuilder createSpanBuilder(String operationName) {
return new AbstractSpanBuilder(operationName) {
@Override
protected AbstractSpan createSpan() {
return new AbstractSpan(this.operationName) {
SpanContext spanContext = new TestSpanContextImpl("op=" + operationName);

@Override
public SpanContext context() {
return spanContext;
}
};
return new TestSpanImpl(this.operationName);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,35 @@

public class TestSpanContextImpl implements SpanContext {
final String marker;
protected Map<String, String> baggage = new HashMap<String, String>();
protected final Map<String, String> baggage;

public TestSpanContextImpl(String marker) {
this.marker = marker;
this(marker, new HashMap<>());
}

public String getMarker() { return marker; }
public TestSpanContextImpl(String marker, Map<String, String> adoptedBaggage) {
this.marker = marker;
this.baggage = adoptedBaggage;
}

@Override
public synchronized SpanContext setBaggageItem(String key, String value) {
this.baggage.put(key, value);
return this;
public Iterable<Map.Entry<String, String>> baggageItems() {
return baggage.entrySet();
}

@Override
public synchronized String getBaggageItem(String key) {
return this.baggage.get(key);
///////////////////////////////////////////////////////////////////////////////////
// Implementation-specific extensions (mainly to support the immutable idiom here).
///////////////////////////////////////////////////////////////////////////////////

public TestSpanContextImpl withBaggageItem(String key, String val) {
Map<String, String> baggageCopy = new HashMap<>(baggage);
baggageCopy.put(key, val);
return new TestSpanContextImpl(marker, baggageCopy);
}

public String getBaggageItem(String key) {
return baggage.get(key);
}

public String getMarker() { return marker; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2016 The OpenTracing Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package io.opentracing;

public class TestSpanImpl extends AbstractSpan {
TestSpanContextImpl spanContext = new TestSpanContextImpl("whatever");

TestSpanImpl(String operationName) {
super(operationName);
}

@Override
public SpanContext context() {
return spanContext;
}

@Override
public synchronized Span setBaggageItem(String key, String value) {
spanContext = spanContext.withBaggageItem(key, value);
return this;
}

@Override
public synchronized String getBaggageItem(String key) {
return spanContext.getBaggageItem(key);
}
}
6 changes: 6 additions & 0 deletions opentracing-impl/src/main/java/io/opentracing/NoopSpan.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,10 @@ public Span log(long timestampMicroseconds, String eventName, Object payload) {
return this;
}

@Override
public Span setBaggageItem(String key, String value) { return this; }

@Override
public String getBaggageItem(String key) { return null; }

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
*/
package io.opentracing;

import java.util.HashMap;
import java.util.Map;

public class NoopSpanContext implements SpanContext {
@Override
public SpanContext setBaggageItem(String key, String value) {
return this;
}
private static Map<String, String> EMPTY_MAP = new HashMap<>();

@Override
public String getBaggageItem(String key) {
return null;
public Iterable<Map.Entry<String, String>> baggageItems() {
return EMPTY_MAP.entrySet();
}
}

0 comments on commit 24be419

Please sign in to comment.