some fixes again
This commit is contained in:
@@ -148,6 +148,12 @@ void DataProcessor::run(const std::atomic<bool>& stop_requested) {
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(config_.runtime.idle_sleep_ms));
|
||||
} catch (const std::exception& exc) {
|
||||
// A ring-slot-too-small failure is a permanent config error (the slot
|
||||
// cannot hold a serialized collection): swallowing it would silently
|
||||
// drop every collection forever, so fail fast and let the operator fix it.
|
||||
if (std::string(exc.what()).find("slot is too small") != std::string::npos) {
|
||||
throw;
|
||||
}
|
||||
// A single bad collection (torn ring slot, decode/processing error) must
|
||||
// not kill the long-running processor: drop it and keep going. Throttle
|
||||
// logging and pause briefly so a persistent error cannot busy-spin/flood.
|
||||
|
||||
@@ -18,14 +18,15 @@
|
||||
namespace radar::locator {
|
||||
|
||||
// Bounded, in-memory packet queue used by the per-client writer thread.
|
||||
// Marking the queue as full closes the client (back-pressure by disconnect),
|
||||
// matching the semantics of the previous Python implementation.
|
||||
// Latest-wins: when full, the oldest queued packet(s) are dropped so a slow
|
||||
// client always advances toward the freshest result. A slow client is never
|
||||
// disconnected (freshness over completeness; bounded memory).
|
||||
class ClientQueue {
|
||||
public:
|
||||
explicit ClientQueue(std::size_t capacity);
|
||||
|
||||
// Push a packet onto the queue. Returns false if the queue is full or has
|
||||
// been closed; the caller is expected to disconnect the client in that case.
|
||||
// Push a packet onto the queue, dropping the oldest entry first if full.
|
||||
// Returns false ONLY when the queue is closed (the session is shutting down).
|
||||
[[nodiscard]] auto try_push(std::vector<std::uint8_t> packet) -> bool;
|
||||
|
||||
// Block until a packet is available or the queue is closed.
|
||||
@@ -68,8 +69,8 @@ class ClientSession {
|
||||
// timestamp slot records when, so the server can expire stale speeds.
|
||||
void start(std::atomic<double>& shared_vlc_slot, std::atomic<std::int64_t>& shared_vlc_at_ns);
|
||||
|
||||
// Enqueue one outbound packet. Disconnects this session if the queue is
|
||||
// already full or the writer has stopped.
|
||||
// Enqueue one outbound packet. Never disconnects a slow client: a full queue
|
||||
// drops its oldest entry (latest-wins). A no-op once the session has stopped.
|
||||
void enqueue(std::vector<std::uint8_t> packet);
|
||||
|
||||
// Initiate teardown of this client (idempotent): closes the queue and
|
||||
@@ -107,9 +108,9 @@ class ClientSession {
|
||||
// * Threading: one acceptor thread + two threads per connected client. The
|
||||
// producer (data_processor) calls publish() synchronously; that call is
|
||||
// non-blocking and never throws for typical operation.
|
||||
// * Back-pressure: each client has its own bounded outbound queue. If a
|
||||
// client is too slow to drain, the next publish() drops it (matches the
|
||||
// prior Python service). Other clients are unaffected.
|
||||
// * Back-pressure: each client has its own bounded outbound queue. A client
|
||||
// too slow to drain is never disconnected; its queue drops the oldest
|
||||
// packet(s) (latest-wins) so it keeps the freshest data. Clients are isolated.
|
||||
// * Latest-snapshot: the most recently published packet is cached and sent
|
||||
// to every newly connected client before any new packets are forwarded.
|
||||
// * Lifetime: `start()` may throw on listen failure. `stop()` is idempotent
|
||||
|
||||
Reference in New Issue
Block a user