fwt_software/include/fgc/ChannelHistory.h

54 lines
1.9 KiB
C++

#pragma once
#include "fgc/IControlChannel.h"
#include <cstddef>
#include <deque>
#include <mutex>
#include <string>
#include <vector>
namespace fgc {
// A bounded, thread-safe record of recent control-channel traffic, plus the
// cumulative counters behind the connectivity view.
//
// It lives here rather than inside MqttControlChannel for two reasons: the null
// channel keeps the same history (so the view works with --no-mqtt), and holding
// no MQTT types means the counter logic is unit-testable with WITH_MQTT=OFF.
//
// Its mutex is its own, deliberately not MqttControlChannel's: that one guards
// sub_data_ and is taken by poll() on the control thread, while record() is
// called from the Paho callback thread and from publish() on both the control
// and ImagePipeline worker threads. Separate locks also keep the history lock
// off the 3-second publish wait.
class ChannelHistory {
public:
// Newest-first eviction bound. Enough to cover a scan's worth of waypoints
// without making the per-tick snapshot copy expensive.
static constexpr std::size_t kCapacity = 40;
// Anything but Delivery::Ok on an outbound message means it never reached the
// broker. Those are the entries worth looking for.
void record(bool outbound, Delivery delivery, std::string topic, std::string payload);
void noteConnect();
void noteLoss();
// What actually went out on the StatusCode topic. The connectivity view used
// to infer this from the live control code, which assumes the echo rather
// than reporting the send.
void noteStatus(std::string payload);
// Oldest first, so the view can print it top-to-bottom as it happened.
std::vector<ChannelMessage> recent() const;
ChannelStats stats() const;
private:
mutable std::mutex mutex_;
std::deque<ChannelMessage> ring_;
ChannelStats stats_;
};
} // namespace fgc