Changes from sync
ADD
dd-trace-ext/src/main/java/datadog/trace/tracer/ext/Examples.java
+package datadog.trace.tracer.ext;
+
+import datadog.trace.tracer.Span;
+import datadog.trace.tracer.Trace;
+import datadog.trace.tracer.Tracer;
+
+// Keeping in PR for potential discussions. Will eventually remove.
+// TODO: remove
+class Examples {
+ private Examples() {}
+
+ public static void test() {
+ final Throwable someThrowable = null;
+ // registration
+ TracerContext.registerGlobalContext(new TracerContext(new Tracer()), false);
+
+ // scope
+ final TracerContext ctx = TracerContext.getGlobalContext();
+ // without try-with-resources
+ {
+ Span rootSpan = ctx.getTracer().buildTrace(null);
+ final Scope scope = ctx.pushScope(rootSpan);
+ rootSpan.setError(true);
+ rootSpan.attachThrowable(someThrowable);
+ scope.close();
+ rootSpan.finish();
+ }
+
+ /*
+ // with try-with-resources finishOnClose=true
+ {
+ Span rootSpan = ctx.getTracer().buildTrace(null);
+ try (Scope scope = ctx.pushScope(rootSpan)) {
+ try {
+ // the body
+ } catch (Throwable t) {
+ rootSpan.setError(true);
+ rootSpan.attachThrowable(t);
+ throw t;
+ }
+ }
+ }
+ */
+
+ // with try-with-resources finishOnClose=false
+ {
+ Span rootSpan = ctx.getTracer().buildTrace(null);
+ try (Scope scope = ctx.pushScope(rootSpan)) {
+ // the body
+ } catch (Throwable t) {
+ rootSpan.setError(true);
+ rootSpan.attachThrowable(t);
+ throw t;
+ } finally {
+ rootSpan.finish();
+ }
+ }
+
+ // continuations
+ {
+ Span rootSpan = ctx.getTracer().buildTrace(null);
+ final Trace.Continuation cont = rootSpan.getTrace().createContinuation(rootSpan);
+ { // on another thread
+ final Span parent = cont.span();
+ try {
+ // body
+ } finally {
+ cont.close();
+ }
+ }
+ }
+
+ // create a span as a child of the currently active span
+ Span childSpan = ctx.peekScope().span().getTrace().createSpan(ctx.peekScope().span());
+ }
+}

MODIFY
dd-trace-ext/src/main/java/datadog/trace/tracer/ext/Scope.java
dd-trace-ext/src/main/java/datadog/trace/tracer/ext/Scope.java
@@ -7,12 +7,12 @@ import datadog.trace.tracer.Trace;
* A scope holds a single span or trace continuation and may optionally finish its span or
* continuation.
*
- * <p>To create a scope, see {@link TracerContext#pushScope(Span, boolean)} and {@link
- * TracerContext#pushScope(Trace.Continuation, boolean)}.
+ * <p>To create a scope, see {@link TracerContext#pushScope(Span)} and {@link
+ * TracerContext#pushScope(Trace.Continuation)}.
*
* <p>All created scopes must be closed with {@link Scope#close()}
*/
-public interface Scope {
+public interface Scope extends AutoCloseable {
/** Get the span held by this scope. */
Span span();
@@ -20,7 +20,7 @@ public interface Scope {
* Close this scope. This method must be invoked on all created scopes.
*
* <p>Attempting to close a scope which is not on the top of its TracerContext's scope-stack is an
- * error. See {@link TracerContext#topOfScopeStack()}.
+ * error. See {@link TracerContext#peekScope()}.
*/
void close();
}

MODIFY
dd-trace-ext/src/main/java/datadog/trace/tracer/ext/TracerContext.java
dd-trace-ext/src/main/java/datadog/trace/tracer/ext/TracerContext.java
@@ -53,10 +53,9 @@ public final class TracerContext {
* Push a new scope to the top of this scope-stack. The scope's span will be the given span.
*
* @param span
- * @param finishSpanOnScopeClose
* @return
*/
- public Scope pushScope(Span span, boolean finishSpanOnScopeClose) {
+ public Scope pushScope(Span span) {
return null;
}
@@ -65,10 +64,9 @@ public final class TracerContext {
* span.
*
* @param continuation
- * @param closeContinuationOnScopeClose
* @return
*/
- public Scope pushScope(Trace.Continuation continuation, boolean closeContinuationOnScopeClose) {
+ public Scope pushScope(Trace.Continuation continuation) {
return null;
}

MODIFY
dd-trace/dd-trace.gradle
dd-trace/dd-trace.gradle
description = 'dd-trace'
apply from: "${rootDir}/gradle/java.gradle"
-// TODO: Move over any special setups from dd-trace-ot (e.g. trace-agent integration tests).
-
dependencies {
annotationProcessor deps.autoservice
implementation deps.autoservice

MODIFY
dd-trace/src/main/java/datadog/trace/tracer/Span.java
dd-trace/src/main/java/datadog/trace/tracer/Span.java
@@ -28,13 +28,6 @@ public interface Span {
/** Returns true if a finish method has been invoked on this span. */
boolean isFinished();
- /**
- * Attach a {@link LifecycleInterceptor} to this span.
- *
- * @param interceptor the interceptor to attach.
- */
- void addInterceptor(LifecycleInterceptor interceptor);
-
/**
* Get the span context for this span.
*
@@ -88,7 +81,7 @@ public interface Span {
boolean isErrored();
/** Attach a throwable to this span. */
- void attachThrowable();
+ void attachThrowable(Throwable t);
/**
* Mark the span as having an error.
@@ -101,10 +94,9 @@ public interface Span {
// does not implement.
/**
- * A LifecycleInterceptor allows adding hooks to particular events between a span starting and
- * finishing.
+ * A Interceptor allows adding hooks to particular events between a span starting and finishing.
*/
- interface LifecycleInterceptor {
+ interface Interceptor {
/**
* Called after a span is started.
*

MODIFY
dd-trace/src/main/java/datadog/trace/tracer/SpanImpl.java
dd-trace/src/main/java/datadog/trace/tracer/SpanImpl.java
package datadog.trace.tracer;
+import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
public class SpanImpl implements Span {
private final Clock clock = null;
@@ -17,7 +19,7 @@ public class SpanImpl implements Span {
/* The start time of the request in nanoseconds from the unix epoch. */
private final long startEpochNano = -1;
/* Duration of the span in nanoseconds */
- private final long durationNano = -1;
+ private final AtomicLong durationNano = new AtomicLong(-1);
// optional attributes to report to datadog
/* The type of the span (web, db, etc). See DDSpanTypes. */
private final String type = null;
@@ -29,19 +31,32 @@ public class SpanImpl implements Span {
/**
* Create a span with a start time of the current timestamp.
*
+ * @param trace The trace to associate this span with
* @param parentContext identifies the parent of this span. May be null.
* @param clock The clock to use to measure the span's duration.
+ * @param interceptors interceptors to run on the span
*/
- SpanImpl(final SpanContext parentContext, final Clock clock) {}
+ SpanImpl(
+ final TraceImpl trace,
+ final SpanContext parentContext,
+ final Clock clock,
+ List<Interceptor> interceptors) {}
/**
* Create a span with the a specific start timestamp.
*
+ * @param trace The trace to associate this span with
* @param parentContext identifies the parent of this span. May be null.
* @param clock The clock to use to measure the span's duration.
+ * @param interceptors interceptors to run on the span
* @param startTimestampNanoseconds Epoch time in nanoseconds when this span started.
*/
- SpanImpl(final SpanContext parentContext, final Clock clock, final long startTimestampNanoseconds) {}
+ SpanImpl(
+ final TraceImpl trace,
+ final SpanContext parentContext,
+ final Clock clock,
+ List<Interceptor> interceptors,
+ final long startTimestampNanoseconds) {}
@Override
public Trace getTrace() {
@@ -60,14 +75,11 @@ public class SpanImpl implements Span {
}
@Override
- public void attachThrowable() {}
+ public void attachThrowable(Throwable t) {}
@Override
public void setError(boolean isErrored) {}
- @Override
- public void addInterceptor(LifecycleInterceptor interceptor) {}
-
@Override
public SpanContext getContext() {
return null;

MODIFY
dd-trace/src/main/java/datadog/trace/tracer/Trace.java
dd-trace/src/main/java/datadog/trace/tracer/Trace.java
@@ -34,7 +34,7 @@ public interface Trace {
*/
Continuation createContinuation(Span parentSpan);
- interface LifecycleInterceptor {
+ interface Interceptor {
/**
* Invoked when a trace is eligible for writing but hasn't been handed off to its writer yet.
*
@@ -52,5 +52,8 @@ public interface Trace {
* <p>Has no effect after the first invocation.
*/
void close();
+
+ // TODO: doc
+ Span span();
}
}

MODIFY
dd-trace/src/main/java/datadog/trace/tracer/TraceImpl.java
dd-trace/src/main/java/datadog/trace/tracer/TraceImpl.java
package datadog.trace.tracer;
import datadog.trace.tracer.writer.Writer;
+import java.lang.ref.WeakReference;
import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.Set;
-public class TraceImpl {
+public class TraceImpl implements Trace {
private final Writer writer = null;
- /**
- * Count of all unfinished spans and continuations.
- *
- * <p>When the count reaches 0 this trace will be reported.
- */
- private final AtomicInteger referenceCount = new AtomicInteger(0);
- /**
- * Thread safe list of spans. List is ordered by span-creation time. The root span will always be
- * the first element. Note that span creation time may differ from span start timestamp (in cases
- * where span creators specify a custom start timestamp).
- *
- * <p>References to these spans are weakly held. If api users create spans but do not finish them
- * we will clean up this trace and increment the trace count with the writer. However, the trace
- * itself will not be reported because incorrect api usage produces suspect data.
- *
- * <p>TODO: There is a potential edge-case with the root span. If the root span is GC'd everything
- * relying on getRootSpan() will break.
- */
- private final List<Span> spans = null;
+ // TODO: Document approach to weak-referencdes and cleanup. If a span has to be closed by our GC
+ // logic the trace should increment the writer's count but not report (invalid api usage produces
+ // suspect data).
+ private final Set<WeakReference<Span>> inFlightSpans = null;
+ private final Set<WeakReference<Trace.Continuation>> inFlightContinuations = null;
+
+ /** Strong refs to spans which are closed */
+ private final List<Span> finishedSpans = null;
+
+ private final Span rootSpan = null;
/**
* Create a new Trace.
*
* @param tracer the Tracer to apply settings from.
*/
- TraceImpl(Tracer tracer) {}
+ TraceImpl(
+ Tracer tracer,
+ SpanContext rootSpanParentContext,
+ final long rootSpanStartTimestampNanoseconds) {}
+
+ @Override
+ public Tracer getTracer() {
+ return null;
+ }
+
+ @Override
+ public Span getRootSpan() {
+ return null;
+ }
+
+ @Override
+ public Span createSpan(Span parentSpan) {
+ return null;
+ }
+
+ @Override
+ public Continuation createContinuation(Span parentSpan) {
+ return null;
+ }
+
+ // TODO methods to inform the trace that continuations and spans finished/closed. Also be able to
+ // inform trace when a span finishes due to GC.
}

MODIFY
dd-trace/src/main/java/datadog/trace/tracer/Tracer.java
dd-trace/src/main/java/datadog/trace/tracer/Tracer.java
@@ -7,7 +7,7 @@ import datadog.trace.tracer.writer.Writer;
/** A Tracer creates {@link Trace}s and holds common settings across traces. */
public class Tracer {
/** Default service name if none provided on the trace or span */
- private final String serviceName = null;
+ private final String defaultServiceName = null;
/** Writer is an charge of reporting traces and spans to the desired endpoint */
private final Writer writer = null;
/** Sampler defines the sampling policy in order to reduce the number of traces for instance */
@@ -22,7 +22,7 @@ public class Tracer {
*
* @return The root span of the new trace.
*/
- public Span buildTrace() {
+ public Span buildTrace(final SpanContext parentContext) {
return null;
}
@@ -32,12 +32,13 @@ public class Tracer {
* @param rootSpanStartTimestampNanoseconds Epoch time in nanoseconds when the root span started.
* @return The root span of the new trace.
*/
- public Span buildTrace(final long rootSpanStartTimestampNanoseconds) {
+ public Span buildTrace(
+ final SpanContext parentContext, final long rootSpanStartTimestampNanoseconds) {
return null;
}
// TODO: doc inject and extract
-
+ // TODO: inject and extract helpers on span context?
public <T> void inject(final SpanContext spanContext, final Object format, final T carrier) {}
public <T> SpanContext extract(final Object format, final T carrier) {

MODIFY
dd-trace/src/main/java/datadog/trace/tracer/writer/Writer.java
dd-trace/src/main/java/datadog/trace/tracer/writer/Writer.java
package datadog.trace.tracer.writer;
import datadog.trace.tracer.Trace;
-import java.util.List;
/** A writer sends traces to some place. */
public interface Writer {
/**
* Write a trace represented by the entire list of all the finished spans
*
- * @param traces the list of traces to write
+ * @param trace the trace to write
*/
- void write(List<Trace> traces);
+ void write(Trace trace);
/**
- * Inform the writer that traces occurred but will not be written. Used by tracer-side sampling.
- *
- * @param numTraces the number of traces to increment the writer's total count by.
+ * Inform the writer that a trace occurred but will not be written. Used by tracer-side sampling.
*/
- void incrementTraceCount(int numTraces);
+ void incrementTraceCount();
/** Start the writer */
void start();

Changes from sync