fix(network): prevent near-zero bandwidth on rapid event-driven updates

When netlink events (link/addr/route changes) fire between timer
intervals, dp.emit() triggers update() which consumes the byte delta
and resets bandwidth_down_total_. A subsequent timer update sees
near-zero delta, displaying very small bandwidth.

Cache the last computed bandwidth values and skip recalculation
when update() is called within half the interval. Event-driven
updates reuse the cached values instead.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Adrian Lopez
2026-03-30 19:38:24 +02:00
parent 49460defdc
commit 753294dbf4
2 changed files with 30 additions and 12 deletions
+2
View File
@@ -70,6 +70,8 @@ class Network : public ALabel {
unsigned long long bandwidth_down_total_{0}; unsigned long long bandwidth_down_total_{0};
unsigned long long bandwidth_up_total_{0}; unsigned long long bandwidth_up_total_{0};
unsigned long long bandwidth_down_prev_{0};
unsigned long long bandwidth_up_prev_{0};
std::chrono::steady_clock::time_point bandwidth_last_sample_time_; std::chrono::steady_clock::time_point bandwidth_last_sample_time_;
std::string state_; std::string state_;
+18 -2
View File
@@ -280,14 +280,22 @@ auto waybar::modules::Network::update() -> void {
std::string tooltip_format; std::string tooltip_format;
auto now = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now();
auto elapsed_seconds = std::chrono::duration<double>(now - bandwidth_last_sample_time_).count(); auto elapsed_seconds = std::chrono::duration<double>(now - bandwidth_last_sample_time_).count();
auto bandwidth_down = 0ull;
auto bandwidth_up = 0ull;
// Only recalculate bandwidth when enough time has elapsed since the last
// sample. Event-driven dp.emit() calls (link/addr/route changes) can
// trigger update() between timer intervals, which would consume the byte
// delta prematurely and show near-zero bandwidth.
auto min_elapsed = std::chrono::duration<double>(interval_).count() * 0.5;
if (elapsed_seconds >= min_elapsed) {
if (elapsed_seconds <= 0.0) { if (elapsed_seconds <= 0.0) {
elapsed_seconds = std::chrono::duration<double>(interval_).count(); elapsed_seconds = std::chrono::duration<double>(interval_).count();
} }
bandwidth_last_sample_time_ = now; bandwidth_last_sample_time_ = now;
auto bandwidth = readBandwidthUsage(); auto bandwidth = readBandwidthUsage();
auto bandwidth_down = 0ull;
auto bandwidth_up = 0ull;
if (bandwidth.has_value()) { if (bandwidth.has_value()) {
auto down_octets = (*bandwidth).first; auto down_octets = (*bandwidth).first;
auto up_octets = (*bandwidth).second; auto up_octets = (*bandwidth).second;
@@ -297,6 +305,14 @@ auto waybar::modules::Network::update() -> void {
bandwidth_up = up_octets - bandwidth_up_total_; bandwidth_up = up_octets - bandwidth_up_total_;
bandwidth_up_total_ = up_octets; bandwidth_up_total_ = up_octets;
bandwidth_down_prev_ = bandwidth_down;
bandwidth_up_prev_ = bandwidth_up;
}
} else {
bandwidth_down = bandwidth_down_prev_;
bandwidth_up = bandwidth_up_prev_;
elapsed_seconds = std::chrono::duration<double>(interval_).count();
} }
if (!alt_) { if (!alt_) {