|
VLink
2.1.0
A high-performance communication middleware
|
Event-data-recorder engine: a rolling in-memory ring of every live topic, dumped to a bag on demand. More...
#include <cstdint>#include <limits>#include <memory>#include <string>#include <string_view>#include <unordered_map>#include <unordered_set>#include <vector>#include "../base/message_loop.h"#include "../subscriber.h"#include "./discovery_viewer.h"Go to the source code of this file.
Classes | |
| class | vlink::TriggerRecorder |
MessageLoop-based rolling in-memory recorder that dumps a pre/post window to a bag on trigger. More... | |
| struct | vlink::TriggerRecorder::UrlConfig |
Per-URL overrides; any field left negative falls back to the matching Config default. More... | |
| struct | vlink::TriggerRecorder::Config |
| Recorder-wide configuration; passed once to the constructor and read-only afterwards. More... | |
| struct | vlink::TriggerRecorder::TriggerParams |
| Per-trigger parameters; a pure data struct with no RPC or protobuf dependency. More... | |
Namespaces | |
| vlink | |
Event-data-recorder engine: a rolling in-memory ring of every live topic, dumped to a bag on demand.
TriggerRecorder is a self-contained data-plane engine (no RPC, no config parsing – those belong to the caller). It discovers every topic on the bus, subscribes to the raw Bytes of each through a caller-supplied RawSubFactory, and keeps a rolling per-URL ring holding the most recent pre-trigger window. dump() persists the pre + post window around the trigger instant to a bag file, rotating old files. This is the dashcam / EDR pattern: the ring is always recording, the trigger decides what to persist.
* discovery --new URL--> RawSubFactory (caller TU) --> RawSub --Bytes--> [per-URL rolling rings] * | * dump(): serialized, runs on the recorder loop | * v * trigger plugin on_dump_finished() <-- dump_dir bag (.vdb|.vcap) <-- BagWriter <-- [bag plugin? reorder] *
MessageLoop: the constructor validates the Config and acquires every fallible resource (creates Config::dump_dir and constructs the discovery viewer), throwing on failure. async_run() starts discovery + buffering; wait for on_begin() to complete (e.g. invoke_task([](){}).wait()) before calling dump(). quit() stops the loop and abandons a dump still waiting for its post window; wait for is_dumping() to become false first when a dump must be preserved.BagPluginInterface, supplied via bind_bag_interface()) sits inside the write path: its on_write() re-emits frames reordered by the true data-plane time parsed from each payload. Without it frames are written in capture-time (arrival) order.TriggerPluginInterface, via bind_trigger_interface()) observes the recorder life cycle – on_dump_finished() is the upload / archive hook. It never rewrites frames.only_front / only_back restrictions. A global URL whitelist / blacklist selects which topics participate.pre_u + max_post_all + 2*retention_guard of history (max_post_all = the largest post across all enabled URLs), so the ingest hot path needs no "is a trigger active" branch:* pre_u post_u * |<---------------->|<---------------->| dump(T) accepted at T, written after the * ring [==:==================T==================:==] largest effective post of the selected URLs * T-pre_u-guard T+post_u+guard plus retention_guard (immediately when that * selected at acceptance; frames sliced at write post is zero); the guard cushions both * time from the guard-padded ring coverage window boundaries *
Bytes::deep_copy and is amortized O(1); one callback may evict multiple expired or over-limit entries. flush(); frames emitted downstream are synchronous and do not accumulate in an additional bag-writer queue. busy_skip_data drops data while the bag writer is active, leaving time holes for later triggers. destroy_on_offline, offline buffers kept for an in-flight dump can push peak memory above max_cache_size.