mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-23 15:10:34 +00:00
90 lines
3.2 KiB
C++
90 lines
3.2 KiB
C++
#pragma once
|
|
|
|
/** Thread-local discard signaling between SpanGuard and the span processor.
|
|
|
|
SpanGuard::discard() wants to drop a span without sending it to the
|
|
exporter. The OTel SDK calls SpanProcessor::OnEnd() synchronously on the
|
|
same thread that calls Span::End(), so a thread-local flag set just before
|
|
End() and read inside OnEnd() lets FilteringSpanProcessor drop the span
|
|
before it enters the batch export queue.
|
|
|
|
This side-channel avoids inspecting the Recordable's internals (which vary
|
|
by exporter type — SpanData vs OtlpRecordable).
|
|
|
|
The flag is a *private* thread-local member of DiscardScope, mutated only by
|
|
its constructor and destructor. This gives real access control rather than a
|
|
naming convention: no code that includes this header can flip the flag
|
|
directly — it can only enter a DiscardScope (which sets and clears the flag
|
|
over its own lifetime) and observe the state via DiscardScope::isActive().
|
|
Binding set/clear to a scope also means the flag cannot leak onto the next
|
|
span even if End() were to throw.
|
|
|
|
Kept in a separate header to avoid transitive include bloat: SpanGuard.h
|
|
only needs this signaling, not the full Telemetry.h with BasicConfig/Journal.
|
|
|
|
Usage:
|
|
@code
|
|
// In SpanGuard::discard():
|
|
{
|
|
DiscardScope discardScope; // flag set for this scope only
|
|
span->End(); // OnEnd() runs synchronously, sees flag
|
|
} // flag cleared here, unconditionally
|
|
|
|
// In FilteringSpanProcessor::OnEnd():
|
|
if (DiscardScope::isActive())
|
|
return; // drop the span
|
|
@endcode
|
|
|
|
@note Thread safety: the flag is thread-local, so each thread observes only
|
|
its own discard signal — no synchronization is required.
|
|
|
|
@see SpanGuard::discard(), FilteringSpanProcessor (Telemetry.cpp)
|
|
*/
|
|
|
|
namespace xrpl::telemetry {
|
|
|
|
/** RAII guard that marks the current thread's span for discard.
|
|
|
|
Sets the thread-local discard flag on construction and clears it on
|
|
destruction, so a span ended within the guard's scope is dropped by
|
|
FilteringSpanProcessor::OnEnd() while the flag stays confined to that scope.
|
|
The flag is private and mutated only here, so no other code can set it.
|
|
Non-copyable and non-movable — its sole purpose is the scoped flag lifetime.
|
|
*/
|
|
class DiscardScope
|
|
{
|
|
public:
|
|
DiscardScope() noexcept
|
|
{
|
|
discarding = true;
|
|
}
|
|
|
|
~DiscardScope()
|
|
{
|
|
discarding = false;
|
|
}
|
|
|
|
DiscardScope(DiscardScope const&) = delete;
|
|
DiscardScope&
|
|
operator=(DiscardScope const&) = delete;
|
|
DiscardScope(DiscardScope&&) = delete;
|
|
DiscardScope&
|
|
operator=(DiscardScope&&) = delete;
|
|
|
|
/** @return true if the current thread is inside a DiscardScope, i.e. the
|
|
span ending now should be dropped rather than exported. Read by
|
|
FilteringSpanProcessor::OnEnd(). */
|
|
[[nodiscard]] static bool
|
|
isActive() noexcept
|
|
{
|
|
return discarding;
|
|
}
|
|
|
|
private:
|
|
/** Thread-local discard flag. Private, so only this class's ctor/dtor can
|
|
mutate it; observers use isActive(). One instance per thread. */
|
|
inline static thread_local bool discarding = false;
|
|
};
|
|
|
|
} // namespace xrpl::telemetry
|