|
VLink
2.1.0
A high-performance communication middleware
|
Unified plugin contract for rewriting bag traffic on both playback (read) and recording (write). More...
#include <cstdint>#include <string>#include <utility>#include "../base/plugin.h"#include "../impl/types.h"Go to the source code of this file.
Classes | |
| class | vlink::BagPluginInterface |
| Abstract plugin base shared by bag playback and bag recording. More... | |
Namespaces | |
| vlink | |
Unified plugin contract for rewriting bag traffic on both playback (read) and recording (write).
BagPluginInterface is a dynamic plugin loaded through the VLink Plugin framework and attached either to a BagReader (via BagReader::bind_bag_interface()) or to a BagWriter (via BagWriter::bind_bag_interface()). A single class serves both directions; an implementation discovers which side it is bound to through get_direction() and overrides only the hooks for that side.
The two directions are symmetric: each is a frame-forwarding pipeline. The host supplies a downstream sink at bind time and the plugin re-emits every Frame – optionally transformed, dropped, fanned out, or reordered – through that sink. Plugins never touch the raw sink member directly; they emit by calling the single do_callback() helper. Read and write share one callable type (Callback, a const Frame& sink); a plugin overrides the on_read() or on_write() hook for its bound direction.
on_read() receives each frame and re-emits it via do_callback(). URL/type remapping is a separate, once-per-URL hook, convert_url_meta(), applied when the bag is opened. The effective Frame::ser_type / schema_type metadata is populated before on_read() runs.on_write() receives each frame – fully populated with ser_type / schema_type because recording persists them – and re-emits it via do_callback().Both hooks may forward unchanged, transcode (e.g. record a raw image as compressed JPEG by emitting new Frame::data plus a new ser_type / schema_type), drop a frame (by not emitting), fan a frame out into several, or buffer frames and emit them reordered by their true data-plane time – a sliding-window reorder, identical on both sides, typically built on a BagProcessor.
Plugin contract:
| Hook | Dir | Purpose |
|---|---|---|
| bind_direction() | both | At bind time: stored, observable via get_direction() |
| register_callback() | both | At bind time: store the forwarding sink |
| convert_url_meta() | read | Once per URL at open: true = keep, false = drop |
| on_reset() | read | Before a playback session: discard retained session state |
| on_read() | read | Every replayed frame: re-emit via do_callback() |
| on_write() | write | Every frame before persist: re-emit via do_callback() |
| flush() | both | At a completed boundary or detach: drain buffered tail |
| do_callback() | both | Forward one frame to the sink (drop = not call) |
on_read() and on_write() are both pure: an implementation defines both even when it serves a single direction, leaving the unused one as a trivial pass-through (do_callback(frame)) or an empty body.
Lifecycle:
* read : load .so -> bind_direction(kRead) -> register_callback -> convert_url_meta (per URL) * -> on_reset -> [on_read -> do_callback -> callback_ -> user] (per frame) -> flush * write : load .so -> bind_direction(kWrite) -> register_callback * -> on_write (per frame) -> do_callback -> callback_ -> writer persists *
A read pass calls flush() only after natural completion. If the reader observes stop() or jump() before the boundary drain begins, it skips flush(); the next top-level session calls on_reset() to discard that retained tail.