fix(amulegui): keep stats + Kad graphs populated across tab switches - #135
Merged
got3nks merged 2 commits intoJun 12, 2026
Merged
Conversation
…dden CamuleRemoteGuiApp::OnPollTimer only fired stattree->DoRequery() / statgraphs->DoRequery() when the Statistics dialog was the visible tab. Side effect: CStatGraphRem::HandlePacket also calls m_kademliawnd->UpdateGraph(), so leaving Statistics hidden also starved the Kad node-count graph on the Network -> Kad sub-tab. Promote both polls out of the visibility gate; they run every step 2 cycle. Cost stays small because the graph request is a delta (m_lastTimestamp lower bound) and the tree request is already throttled by thePrefs::GetStatsInterval(). Reported in amule-project#134.
…ory ring
COScopeCtrl::PlotHistory had an empty stub under CLIENT_GUI because
the monolithic implementation called theApp->m_statistics->GetHistory
which had no analogue on the remote-GUI side. Two visible regressions
fell out of that gap:
* Switching off the Stats / Kad tab and back left a gap on the graph
-- the OnPaint "come out of hiding" catch-up via PlotHistory was a
no-op, so the bitmap never refilled the hidden interval.
* Auto-rescale events (Kad node count crossing a 50-step ceiling,
Stats connection scope changing scale) called RecreateGraph which
cleared the bitmap and then called the empty PlotHistory, blanking
the entire graph.
Share the monolithic machinery instead of duplicating it. The HR
struct was already outside the #ifndef CLIENT_GUI gate; lift
CPreciseRateCounter, CStatistics::GetHistory and
CStatistics::ComputeAverages out alongside it. The CLIENT_GUI
CStatistics now also carries listHR + the three m_graphRunningAvg*
counters + hrInit, plus a new CLIENT_GUI-only producer
AddHistoryRecord that CStatGraphRem::HandlePacket calls once per
decoded point. The ring is capped at kHistoryCap=1800 (~30 min @ 1Hz)
so memory stays bounded across long sessions. With listHR populated,
the shared PlotHistory body works for both builds and the
CLIENT_GUI-specific stub is gone.
Field mapping in HandlePacket mirrors CStatistics::GetPointsForUpdate
so the same GetHistory + ComputeAverages code reads it back correctly:
kBytes{Received,Sent} and kadNodesTotal are stored as
(session-rate * timestamp), so ComputeAverages's "kValueRun /
sTimestamp" recovers the session-avg trend ([0]) verbatim. Per-point
timestamps are reconstructed from the batch by stepping back from
m_lastTimestamp at the 1s scale we request in DoRequery.
Statistics.h gains "#include GetTickCount.h" because the now-shared
CPreciseRateCounter inline ctor calls GetTickCount64 and was
previously only instantiated under #ifndef CLIENT_GUI where transitive
includes covered it.
Verified locally on macOS that monolithic amule and amulegui both
build cleanly (BUILD_MONOLITHIC=YES BUILD_REMOTEGUI=YES
BUILD_DAEMON=YES).
Reported in amule-project#134.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #134 (stats + Kad parts).
Two visible regressions on amulegui's Statistics tab and the Network → Kad sub-tab, both rooted in the same gap:
COScopeCtrl::PlotHistorywas an empty stub underCLIENT_GUIbecause the monolithic implementation callstheApp->m_statistics->GetHistory(...)which had no analogue on the remote-GUI side. Two symptoms:CamuleRemoteGuiApp::OnPollTimeronly firedstatgraphs->DoRequery()andstattree->DoRequery()when the Statistics dialog was visible.CStatGraphRem::HandlePacketalso feedsm_kademliawnd->UpdateGraph(), so leaving Statistics hidden also starved the Kad node-count graph. Switch off Stats → both graphs froze.SetRangeson Kad node count crossing a 50-step ceiling;SetRangeon the Stats connection-scopenScalechange) callRecreateGraph, which clears the bitmap and then callsPlotHistory(width, false, ...). Under CLIENT_GUI that was a no-op, so the bitmap stayed cleared and the entire line vanished.What this PR does
Commit 1 — polling-gate fix. Both stats requests now run every step 2 cycle regardless of the active tab. Cost is unchanged in practice: the graph request is a delta (
m_lastTimestamplower bound; daemon returns only newer points orEC_OP_FAILED "No points for graph.") and the tree request is already throttled bythePrefs::GetStatsInterval().Commit 2 — share
PlotHistorywith monolithic via a client-side history ring. Rather than duplicate the monolithic machinery,CPreciseRateCounter,CStatistics::GetHistoryandCStatistics::ComputeAveragesare lifted out of the#ifndef CLIENT_GUIgate alongside the already-sharedHRstruct. The CLIENT_GUICStatisticsnow also carrieslistHR, the threem_graphRunningAvg*counters andhrInit. A new CLIENT_GUI-only producerAddHistoryRecord(const HR&)is called once per decoded point fromCStatGraphRem::HandlePacket. The ring is capped atkHistoryCap = 1800(~30 min @ 1 Hz, ≈150 KB across all four graphs). WithlistHRpopulated the sharedPlotHistorybody works under both builds and the CLIENT_GUI-specific empty stub is gone.Field mapping in
HandlePacketmirrorsCStatistics::GetPointsForUpdateso the sameGetHistory+ComputeAveragescode reads it back correctly:kBytes{Received,Sent}andkadNodesTotalare stored assession-rate * timestamp, soComputeAverages'skValueRun / sTimestamprecovers the session-avg trend[0]verbatim. Per-point timestamps are reconstructed from the batch by stepping back fromm_lastTimestampat the 1 s scale we request inDoRequery.No EC protocol changes
The ring fills from the existing
EC_OP_GET_STATSGRAPHSstream — no new tags, no version bump, fully backward compatible with old daemons.Test plan
nScalechange.amule.appbuilds cleanly withBUILD_MONOLITHIC=YES BUILD_REMOTEGUI=YES BUILD_DAEMON=YES; no regression in monolithic graph behavior (history machinery is the same code paths, just no longer#ifdef-gated).listHRcapped at 1800 records → bounded at ~150 KB total.