54 lines
1.9 KiB
C++
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
|