mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-24 07:30:30 +00:00
refactor(telemetry): add detachInPlace() helpers to remove hand-rolled SpanGuard re-detach idiom
Add two free functions in xrpl::telemetry that wrap the required "detach a live SpanGuard held in a container" idiom so call sites write one line instead of the make_shared/emplace rebuild by hand: void detachInPlace(std::optional<SpanGuard>&); std::shared_ptr<SpanGuard> detachInPlace(std::shared_ptr<SpanGuard>); Both are no-ops on an empty/null/inactive guard. The #else branch adds matching inline no-op stubs so callers compile with telemetry disabled. Pure API addition, no behavior change; consumer call sites are rewritten on phase4 in a follow-up. The unit tests for these helpers land on phase2, where the telemetry test module (in-memory-exporter harness + SpanGuardScope.cpp) exists — mirroring how the detached()/rootSpan() tests were placed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -164,6 +164,7 @@
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
namespace xrpl::telemetry {
|
||||
@@ -426,6 +427,43 @@ public:
|
||||
operator bool() const;
|
||||
};
|
||||
|
||||
// --- Detach-in-place helpers -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Detach an active `std::optional<SpanGuard>` member in place.
|
||||
*
|
||||
* Equivalent to `guard.emplace(std::move(*guard).detached())`, which is the
|
||||
* required idiom for detaching a live guard stored in an `optional` (move
|
||||
* assignment is deleted because the underlying Scope cannot be re-scoped in
|
||||
* place). No-op if `guard` is empty or already null.
|
||||
*
|
||||
* @param guard The optional guard to detach. Must be called on the thread
|
||||
* that constructed the active guard inside it (same rule as
|
||||
* `SpanGuard::detached()`).
|
||||
* @note Must run BEFORE any `captureContext()` snapshot is taken if the
|
||||
* caller also needs the pre-detach context — capture first, then call
|
||||
* this helper (same ordering rule `detached()` itself has).
|
||||
*/
|
||||
void
|
||||
detachInPlace(std::optional<SpanGuard>& guard);
|
||||
|
||||
/**
|
||||
* Detach an active `std::shared_ptr<SpanGuard>`, returning the detached
|
||||
* guard as a new `shared_ptr`.
|
||||
*
|
||||
* Equivalent to
|
||||
* `guard = std::make_shared<SpanGuard>(std::move(*guard).detached())`.
|
||||
* No-op (returns the input unchanged) if `guard` is null or points at a
|
||||
* null guard.
|
||||
*
|
||||
* @param guard The guard to detach, taken by value (the caller's pointer
|
||||
* is consumed; assign the return value back).
|
||||
* @return A `shared_ptr` to the detached guard (new allocation), or the
|
||||
* input pointer unchanged if it was null/inactive.
|
||||
*/
|
||||
[[nodiscard]] std::shared_ptr<SpanGuard>
|
||||
detachInPlace(std::shared_ptr<SpanGuard> guard);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// No-op stub (all inline, zero overhead, no OTel dependency)
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -539,6 +577,19 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// --- Detach-in-place helpers (no-op stubs) ---------------------------------
|
||||
|
||||
inline void
|
||||
detachInPlace(std::optional<SpanGuard>&)
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::shared_ptr<SpanGuard>
|
||||
detachInPlace(std::shared_ptr<SpanGuard> guard)
|
||||
{
|
||||
return guard;
|
||||
}
|
||||
|
||||
#endif // XRPL_ENABLE_TELEMETRY
|
||||
|
||||
} // namespace xrpl::telemetry
|
||||
|
||||
@@ -321,6 +321,24 @@ SpanGuard::detached() &&
|
||||
return SpanGuard(std::make_unique<Impl>(std::move(s), Impl::Detached{}));
|
||||
}
|
||||
|
||||
// ===== Detach-in-place helpers =============================================
|
||||
|
||||
void
|
||||
detachInPlace(std::optional<SpanGuard>& guard)
|
||||
{
|
||||
if (!guard || !*guard)
|
||||
return;
|
||||
guard.emplace(std::move(*guard).detached());
|
||||
}
|
||||
|
||||
std::shared_ptr<SpanGuard>
|
||||
detachInPlace(std::shared_ptr<SpanGuard> guard)
|
||||
{
|
||||
if (!guard || !*guard)
|
||||
return guard;
|
||||
return std::make_shared<SpanGuard>(std::move(*guard).detached());
|
||||
}
|
||||
|
||||
// ===== Context capture =====================================================
|
||||
|
||||
SpanContext
|
||||
|
||||
Reference in New Issue
Block a user