#include "fgc/ChannelHistory.h" #include namespace fgc { namespace { long long nowMs() { return std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()) .count(); } } // namespace void ChannelHistory::record(bool outbound, Delivery delivery, std::string topic, std::string payload) { std::lock_guard lock(mutex_); if (!outbound) { ++stats_.received; } else { switch (delivery) { case Delivery::Ok: ++stats_.published_ok; break; case Delivery::Dropped: ++stats_.published_dropped; break; case Delivery::Failed: ++stats_.published_failed; break; } } ChannelMessage m; m.timestamp_ms = nowMs(); m.outbound = outbound; m.delivery = delivery; m.topic = std::move(topic); m.payload = std::move(payload); ring_.push_back(std::move(m)); while (ring_.size() > kCapacity) ring_.pop_front(); } void ChannelHistory::noteConnect() { std::lock_guard lock(mutex_); ++stats_.connects; stats_.last_connect_ms = nowMs(); } void ChannelHistory::noteStatus(std::string payload) { std::lock_guard lock(mutex_); stats_.last_status_payload = std::move(payload); } void ChannelHistory::noteLoss() { std::lock_guard lock(mutex_); stats_.last_loss_ms = nowMs(); } std::vector ChannelHistory::recent() const { std::lock_guard lock(mutex_); return {ring_.begin(), ring_.end()}; } ChannelStats ChannelHistory::stats() const { std::lock_guard lock(mutex_); return stats_; } } // namespace fgc