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

Commit

Permalink
Implement Span::Abandon().
Browse files Browse the repository at this point in the history
  • Loading branch information
g-easy committed Jul 1, 2019
1 parent 858195c commit cac9f3e
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 9 deletions.
13 changes: 12 additions & 1 deletion opencensus/trace/internal/span.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ class SpanGenerator {
SpanContext context(trace_id, span_id, trace_options);
SpanImpl* impl = nullptr;
if (trace_options.IsSampled()) {
// Only Spans that are sampled are backed by a SpanImpl.
// Only Spans that started off sampled are backed by a SpanImpl.
// They can be abandoned later.
impl =
new SpanImpl(context, TraceConfigImpl::Get()->current_trace_params(),
name, parent_span_id, has_remote_parent);
Expand Down Expand Up @@ -216,10 +217,20 @@ void Span::End() const {
}
exporter::RunningSpanStoreImpl::Get()->RemoveSpan(span_impl_);
exporter::LocalSpanStoreImpl::Get()->AddSpan(span_impl_);
// SpanExporterImpl checks if span_impl_ is sampled for export.
exporter::SpanExporterImpl::Get()->AddSpan(span_impl_);
}
}

void Span::Abandon() {
if (IsRecording()) {
context_ = SpanContext(context_.trace_id(), context_.span_id(),
context_.trace_options().WithSampling(false));
span_impl_->MarkAbandoned();
End();
}
}

const SpanContext& Span::context() const { return context_; }

bool Span::IsSampled() const { return context_.trace_options().IsSampled(); }
Expand Down
15 changes: 15 additions & 0 deletions opencensus/trace/internal/span_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ void SpanImpl::SetName(absl::string_view name) {
}
}

void SpanImpl::MarkAbandoned() {
absl::MutexLock l(&mu_);
context_ = SpanContext(context_.trace_id(), context_.span_id(),
context_.trace_options().WithSampling(false));
}

bool SpanImpl::End() {
absl::MutexLock l(&mu_);
if (has_ended_) {
Expand All @@ -161,6 +167,15 @@ bool SpanImpl::HasEnded() const {
return has_ended_;
}

bool SpanImpl::IsSampled() const {
return context().trace_options().IsSampled();
}

SpanContext SpanImpl::context() const {
absl::MutexLock l(&mu_);
return context_;
}

exporter::SpanData SpanImpl::ToSpanData() const {
absl::MutexLock l(&mu_);
// Make a deep copy of attributes.
Expand Down
15 changes: 12 additions & 3 deletions opencensus/trace/internal/span_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,27 @@ class SpanImpl final {

void SetName(absl::string_view name) LOCKS_EXCLUDED(mu_);

void MarkAbandoned() LOCKS_EXCLUDED(mu_);

// Returns true on success (if this is the first time the Span has ended) and
// also marks the end of the Span and sets its end_time_.
bool End() LOCKS_EXCLUDED(mu_);

// Returns true if the span has ended.
// Returns true if the Span has ended.
bool HasEnded() const LOCKS_EXCLUDED(mu_);

// Returns true if the Span is sampled for export. Returns false if the Span
// was abandoned.
bool IsSampled() const LOCKS_EXCLUDED(mu_);

absl::string_view name() const { return name_; }

// Returns the name of the span as a constref string.
const std::string& name_constref() const { return name_; }

// Returns the SpanContext associated with this Span.
SpanContext context() const { return context_; }
// The trace_options do reflect MarkAbandoned().
SpanContext context() const LOCKS_EXCLUDED(mu_);

SpanId parent_span_id() const { return parent_span_id_; }

Expand All @@ -126,7 +133,7 @@ class SpanImpl final {
// a root span.
const SpanId parent_span_id_;
// TraceId, SpanId, and TraceOptions for the current span.
const SpanContext context_;
SpanContext context_ GUARDED_BY(mu_);
// Queue of recorded annotations.
TraceEvents<EventWithTime<exporter::Annotation>> annotations_ GUARDED_BY(mu_);
// Queue of recorded network events.
Expand All @@ -138,6 +145,8 @@ class SpanImpl final {
AttributeList attributes_ GUARDED_BY(mu_);
// Marks if the span has ended.
bool has_ended_ GUARDED_BY(mu_);
// Marks if the span was abandoned.
bool is_abandoned_ GUARDED_BY(mu_);
// True if the parent Span is in a different process.
const bool remote_parent_;
};
Expand Down
10 changes: 10 additions & 0 deletions opencensus/trace/internal/span_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,16 @@ TEST(SpanTest, BlankSpan) {
span.End();
}

TEST(SpanTest, Abandon) {
AlwaysSampler sampler;
auto span = Span::StartSpan("SpanName", /*parent=*/nullptr, {&sampler});
EXPECT_TRUE(span.IsSampled());
span.Abandon();
EXPECT_FALSE(span.IsSampled());
auto data = SpanTestPeer::ToSpanData(&span);
EXPECT_FALSE(data.context().trace_options().IsSampled());
}

} // namespace
} // namespace trace
} // namespace opencensus
16 changes: 11 additions & 5 deletions opencensus/trace/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,11 @@ struct StartSpanOptions {
// implementation-defined data structure, hence all operations on it are marked
// const.
//
// Span is thread-compatible. If swap() and operator= are avoided, everything
// else is thread-safe. Avoid mutating Span objects in-place; treat them like
// read-only handles. When using multiple threads, give each thread a copy of
// the Span.
// Span is thread-compatible. Avoid mutating Span objects in-place; treat them
// like read-only handles. When using multiple threads, give each thread a copy
// of the Span.
//
// Almost everything is thread-safe except: swap(), operator=, Abandon().
//
// As an alternative to explicitly passing Span objects between functions,
// consider using Context. (see the ../context/ directory).
Expand Down Expand Up @@ -154,13 +155,18 @@ class Span final {
void SetStatus(StatusCode canonical_code,
absl::string_view message = "") const;

// Set the span name.
// Set the Span name.
void SetName(absl::string_view name) const;

// Marks the end of a Span. No further changes can be made to the Span after
// End is called.
void End() const;

// If the Span was sampled, un-samples it and End()s it. Note that other
// copies of this Span, and child spans, do not become unsampled.
// TODO(opencensus-specs): Should Abandon() not call End()?
void Abandon();

// Returns the SpanContext associated with this Span.
const SpanContext& context() const;

Expand Down

0 comments on commit cac9f3e

Please sign in to comment.