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:
@@ -70,6 +70,8 @@ class Network : public ALabel {
|
||||
|
||||
unsigned long long bandwidth_down_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::string state_;
|
||||
|
||||
+28
-12
@@ -280,23 +280,39 @@ auto waybar::modules::Network::update() -> void {
|
||||
std::string tooltip_format;
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto elapsed_seconds = std::chrono::duration<double>(now - bandwidth_last_sample_time_).count();
|
||||
if (elapsed_seconds <= 0.0) {
|
||||
elapsed_seconds = std::chrono::duration<double>(interval_).count();
|
||||
}
|
||||
bandwidth_last_sample_time_ = now;
|
||||
|
||||
auto bandwidth = readBandwidthUsage();
|
||||
auto bandwidth_down = 0ull;
|
||||
auto bandwidth_up = 0ull;
|
||||
if (bandwidth.has_value()) {
|
||||
auto down_octets = (*bandwidth).first;
|
||||
auto up_octets = (*bandwidth).second;
|
||||
|
||||
bandwidth_down = down_octets - bandwidth_down_total_;
|
||||
bandwidth_down_total_ = down_octets;
|
||||
// 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) {
|
||||
elapsed_seconds = std::chrono::duration<double>(interval_).count();
|
||||
}
|
||||
bandwidth_last_sample_time_ = now;
|
||||
|
||||
bandwidth_up = up_octets - bandwidth_up_total_;
|
||||
bandwidth_up_total_ = up_octets;
|
||||
auto bandwidth = readBandwidthUsage();
|
||||
if (bandwidth.has_value()) {
|
||||
auto down_octets = (*bandwidth).first;
|
||||
auto up_octets = (*bandwidth).second;
|
||||
|
||||
bandwidth_down = down_octets - bandwidth_down_total_;
|
||||
bandwidth_down_total_ = down_octets;
|
||||
|
||||
bandwidth_up = up_octets - bandwidth_up_total_;
|
||||
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_) {
|
||||
|
||||
Reference in New Issue
Block a user