fix(nodestore): sample writer depth over one population

Depth was observed at insert entry but its sample was only counted at
insert exit, so an insert still in flight contributed nothing to the
mean while completed inserts -- disproportionately the fast, shallow
ones -- all did. The reported mean understated queueing exactly when
queueing was worst: with every writer inside its first insert the gauge
was omitted entirely, while writers-in-flight correctly showed them all.

Depth and its sample count are now both folded in at entry, so the mean
is taken over one population. Mean depth is the L in Little's Law, so a
biased L understated the derived queueing share of each insert.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pratik Mankawde
2026-07-28 18:24:07 +01:00
parent cfa2fd06ca
commit 61b101e147
3 changed files with 41 additions and 5 deletions

View File

@@ -25,7 +25,7 @@ namespace xrpl::node_store {
* |
* concurrentWriters = queue length here
* insertTotalUs / insertCount = time in the whole system (W)
* depthSum / insertCount = mean depth (L)
* depthSum / depthSamples = mean depth (L)
*
* @note All fields except @ref concurrentWriters are cumulative for the
* life of the backend, so a reader must difference successive
@@ -38,7 +38,7 @@ namespace xrpl::node_store {
* if (auto const s = backend->getWriteStats(); s && s->insertCount)
* {
* double const meanUs = double(s->insertTotalUs) / s->insertCount;
* double const meanDepth = double(s->depthSum) / s->insertCount;
* double const meanDepth = double(s->depthSum) / s->depthSamples;
* double const serviceUs = meanUs / meanDepth; // Little's Law
* }
* @endcode
@@ -76,6 +76,15 @@ struct WriteStats
* @ref insertCount this gives mean depth.
*/
std::uint64_t depthSum = 0;
/**
* Number of depth samples summed into @ref depthSum.
*
* Divide @ref depthSum by this, not by @ref insertCount: a sample is
* taken when an insert starts, while insertCount only rises when one
* finishes, so the two populations differ while inserts are in flight.
*/
std::uint64_t depthSamples = 0;
};
} // namespace xrpl::node_store