/// \warning This class is not thread safe. We do not use a mutex
/// because all coroutines spawned by RGWDataSyncCR share a single thread.
class LatencyMonitor {
- ceph::timespan total;
- std::uint64_t count = 0;
+ ceph::timespan avg{ceph::timespan::zero()};
+ bool initialized = false;
+ // Weight for new samples in running average. Recent samples matter
+ // most; after ~20 new samples a past spike decays to <4%.
+ // Example: if avg is poisoned at 30s but real latency is 0.1s,
+ // after 20 good samples the avg drops to ~1.2s (fully recovered).
+ static constexpr double alpha = 0.15;
public:
LatencyMonitor() = default;
void add_latency(ceph::timespan latency) {
- total += latency;
- ++count;
+ if (!initialized) {
+ avg = latency;
+ initialized = true;
+ } else {
+ avg = ceph::timespan(
+ static_cast<ceph::timespan::rep>(
+ alpha * latency.count() + (1.0 - alpha) * avg.count()));
+ }
}
ceph::timespan avg_latency() {
- using namespace std::literals;
- return count == 0 ? 0s : total / count;
+ return avg;
}
};