mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-21 22:30:57 +00:00
Phase-10 brought in the upstream nodestore/peerfinder/consensus reorganisation along with its own write-path telemetry, which collided with the sync-diagnostic signals on this branch. Twelve files conflicted; every resolution keeps both intents rather than picking a side. The nodestore write timing was implemented twice, independently. Both sides added getStoreDurationUs()/getFetchDurationUs() to Database and both timed the backend call in each concrete store(). Keeping both would have added twice to storeDurationUs_ per store while storeStats() still counted one, so the mean write latency would have read double on every dashboard -- silently, since no test on either side asserts an exact microsecond figure. Resolved to one accumulator API: recordStoreDuration(), which takes a duration, clamps a sub-microsecond sample to zero and uses a relaxed atomic add. Phase-10's storeDurationStats() is gone and its two call sites now use the survivor, so all three store paths -- both store() overrides and importInternal() -- add exactly once. SlotCensus and its pure virtual moved from src/xrpld/peerfinder/ to include/xrpl/peerfinder/PeerfinderManager.h, following the Manager interface upstream relocated. The xrpld header is now phase-10's makeConfig shim, and Overlay.h, MetricMacros.cpp and the getSlotCensus() override chain point at the new location. ConsensusSpanNames.h and peerfinder Slot.h/Config.h include paths followed their headers into libxrpl the same way. InboundLedger gained phase-10's AcquireStats counters next to this branch's span activations in both the destructor abort path and done(); neither displaces the other. nodestore_state keeps the constant-based name this branch requires of it and phase-10's fuller description. Upstream #7292 deleted src/test/nodestore/Database_test.cpp, which held this branch's testDurationAccessors. Phase-10 restored the per-store half of that coverage in DatabaseConfig_test, but nothing covered importInternal -- it writes through storeBatch() and never through store(), so it is a third store path that has to time itself. That half is ported to a GTest in src/tests/libxrpl/nodestore/Database.cpp, keeping the exact zero-before and accumulate-after assertions and the per-instance negative check. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
93 lines
3.1 KiB
C++
93 lines
3.1 KiB
C++
#pragma once
|
|
|
|
#include <xrpl/beast/utility/Journal.h>
|
|
#include <xrpl/nodestore/Backend.h>
|
|
#include <xrpl/nodestore/Database.h>
|
|
#include <xrpl/nodestore/Scheduler.h>
|
|
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
namespace xrpl::node_store {
|
|
|
|
/* This class has two key-value store Backend objects for persisting SHAMap
|
|
* records. This facilitates online deletion of data. New backends are
|
|
* rotated in. Old ones are rotated out and deleted.
|
|
*/
|
|
|
|
class DatabaseRotating : public Database
|
|
{
|
|
public:
|
|
DatabaseRotating(
|
|
Scheduler& scheduler,
|
|
int readThreads,
|
|
Section const& config,
|
|
beast::Journal journal)
|
|
: Database(scheduler, readThreads, config, journal)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Rotates the backends.
|
|
*
|
|
* @param newBackend New writable backend
|
|
* @param f A function executed after the rotation outside of lock. The
|
|
* values passed to f will be the new backend database names _after_
|
|
* rotation.
|
|
*/
|
|
virtual void
|
|
rotate(
|
|
std::unique_ptr<node_store::Backend>&& newBackend,
|
|
std::function<void(std::string const& writableName, std::string const& archiveName)> const&
|
|
f) = 0;
|
|
|
|
/**
|
|
* Marks an online-delete rotation as in progress (or completed).
|
|
*
|
|
* While in flight, a read served by the archive backend is copied
|
|
* forward into the writable backend even for ordinary
|
|
* (duplicate == false) fetches: the archive is about to be deleted,
|
|
* and a node body canonicalized into caches during the rotation
|
|
* window would otherwise survive only in RAM once the archive is
|
|
* dropped.
|
|
*/
|
|
virtual void
|
|
setRotationInFlight(bool inFlight) = 0;
|
|
|
|
/**
|
|
* Whether an online-delete rotation is in progress right now.
|
|
*
|
|
* A rotation's extra writes only happen inside this window, so a panel
|
|
* reading the copy-forward total needs this to know when to expect it to
|
|
* move. Outside the window a flat total is correct, not a broken signal.
|
|
*
|
|
* @return true between the cache-freshen phase starting and rotate()
|
|
* completing.
|
|
*/
|
|
[[nodiscard]] virtual bool
|
|
isRotationInFlight() const = 0;
|
|
|
|
/**
|
|
* Nodes copied forward from the archive backend into the writable one
|
|
* during rotation windows, since this process started.
|
|
*
|
|
* These are writes an ordinary fetch would not have performed: the archive
|
|
* is about to be deleted, so a body it served has to be rewritten to
|
|
* survive. The count therefore scales with how much of the archive is read
|
|
* during a rotation, which is why it appears only on a populated,
|
|
* already-rotated online_delete database.
|
|
*
|
|
* Cumulative for the lifetime of the process, deliberately: the per-rotation
|
|
* tally that `rotate()` logs is reset on every swap, and a counter that goes
|
|
* backwards cannot be rated. A panel takes the rate of this instead.
|
|
*
|
|
* @return Monotonic count of copy-forward writes.
|
|
*/
|
|
[[nodiscard]] virtual std::uint64_t
|
|
copyForwardTotal() const = 0;
|
|
};
|
|
|
|
} // namespace xrpl::node_store
|