![]() |
Cockatrice 2026-10-19-Development-3.1.2-beta.2
A virtual tabletop for multiplayer card games
|
Lock-free accumulation of command processing statistics. More...
#include <metrics_registry.h>
Classes | |
| struct | ActiveTypeStats |
| struct | GameStartSnapshot |
| struct | TypeStats |
Public Member Functions | |
| void | observeCommand (int typeId, qint64 elapsedMs) |
| void | observeGameStartDurationMs (qint64 elapsedMs) |
| qint64 | totalCommands () const |
| Total number of observed commands across all types. | |
| qint64 | totalTimeMs () const |
| Cumulative processing milliseconds across all types. | |
| int | activeTypeCount () const |
| Number of distinct type slots that have seen at least one sample. | |
| QList< ActiveTypeStats > | collectActiveStats () const |
| GameStartSnapshot | getGameStartSnapshot () const |
Static Public Member Functions | |
| static int | typeIdFor (int kindIndex, int extensionNumber) |
| Guard against typeIdFor() overflowing into the neighbouring kind's slots. | |
Static Public Attributes | |
| static constexpr int | KindStride = 1280 |
| static constexpr int | NumKinds = 6 |
| static constexpr const char * | KindNames [NumKinds] = {"session", "room", "game", "moderator", "admin", "developer"} |
| static constexpr int | MaxTypes = NumKinds * KindStride |
| Upper bound on distinct command type ids (see typeIdFor). | |
Private Member Functions | |
| TypeStats & | slotFor (int typeId) |
| const TypeStats & | slotFor (int typeId) const |
Private Attributes | |
| std::array< TypeStats, MaxTypes > | typeSlots {} |
| TypeStats | gameStartStats {} |
| std::atomic< qint64 > | totalCommandsCounter {0} |
| std::atomic< qint64 > | totalTimeCounter {0} |
Lock-free accumulation of command processing statistics.
observeCommand() is called once per processed command from whichever socket thread handled it. It uses relaxed atomic adds on preallocated storage only, so it introduces no locks, allocations, or shared cache-line ping-pong beyond the unavoidable counter updates.
Reading happens rarely (metrics scraping), accepts momentary tears between related counters, and therefore also needs no synchronization.
Only counts and totals are retained. An earlier Prometheus-style cumulative histogram (per-type, time-bucketed) was cut because nothing in the server ever wrote it out; it belongs to the future /metrics exporter that needs it.
| int MetricsRegistry::activeTypeCount | ( | ) | const |
Number of distinct type slots that have seen at least one sample.
| QList< MetricsRegistry::ActiveTypeStats > MetricsRegistry::collectActiveStats | ( | ) | const |
Returns stats for every type slot that has seen at least one sample. Callers resolve the numeric type id to a human-readable label via typeIdFor()/KindNames as needed.
| MetricsRegistry::GameStartSnapshot MetricsRegistry::getGameStartSnapshot | ( | ) | const |
| void MetricsRegistry::observeCommand | ( | int | typeId, |
| qint64 | elapsedMs ) |
| void MetricsRegistry::observeGameStartDurationMs | ( | qint64 | elapsedMs | ) |
Records how long one game start took to bring every player's zones online. Kept separate from command timings because it is triggered by the server itself and can dwarf any single command when decks are huge.
|
private |
|
private |
|
inline |
Total number of observed commands across all types.
|
inline |
Cumulative processing milliseconds across all types.
|
inlinestatic |
Guard against typeIdFor() overflowing into the neighbouring kind's slots.
|
private |
|
staticconstexpr |
|
staticconstexpr |
Extension numbers are only unique per command kind, so recorded ids combine the kind index with the protobuf extension number.
The stride is only as wide as it needs to be: 1280 is the first round number above the largest extension actually in use (ModeratorCommand = 1206) and keeps the preallocated TypeStats array small. Bump it if a new command exceeds it.
|
staticconstexpr |
Upper bound on distinct command type ids (see typeIdFor).
|
staticconstexpr |
|
private |
|
private |