- New fabric-bridge node: initiator mode reads local MXL flow and
transfers via Fabrics (RDMA/TCP); target mode receives remote data
and commits to local MXL flow writer
- Add set_mxl_instance/get_mxl_instance to Node base class
- CMake option DMF_BUILD_FABRICS=OFF by default (needs libfabric)
- Target publishes target_info in status for out-of-band exchange
- Initiator receives target_info via config parameter
- node_runner: track all readers/writers in flow_resources vector,
release them via mxlReleaseFlowWriter/mxlReleaseFlowReader before
destroying the MXL instance (fixes 'leaked flow writer' warning)
- node_runner: remove_writer/remove_reader commands now also release
the MXL flow resources, not just reset the node's optional<>
- engine: call process_manager.stop_all(graph) on shutdown to kill
child node processes (prevents orphaned passthrough processes)
- graph: add get_node_mut() for process_manager to update node state
- process_manager: implement stop_all(Graph&) that SIGTERMs all
running node processes
- passthrough: reduce logging to first-grain and realign-once only
- tests: update flow format assertion to match NMOS
(urn:x-nmos:format:video instead of video/v210)
The fundamental issue: mxlSleepUntil/mxlSleepForNs blocks the entire
thread, making LWS unresponsive and causing control commands to hang.
Meanwhile, LWS poll(1) adds latency that makes grain timing unreliable.
Solution: run node->process() in a dedicated thread that can freely use
mxlSleepUntil for precise grain timing, while the main thread runs
control_server->poll(10) for LWS event handling.
Passthrough now uses mxlSleepUntil(deadline) matching the mxl-gst-sink
Cursor pattern, with 2-grain read delay for buffering.
- control_server: add Connection: close header + always return -1 after
HTTP response to force-close connection. Without this, lws_service()
blocks forever after the first POST /cmd, freezing the node process loop.
- passthrough: initialize read_index_ to runtime.headIndex when reader
is added (prevents TOO_EARLY errors on first read)
- passthrough: handle MXL_ERR_OUT_OF_RANGE_TOO_EARLY in addition to
TOO_LATE (both jump to head index)
- passthrough: use grain_info.index as writer index instead of separate
write_index_ counter (MXL writers must use TAI-based grain indices)
- passthrough: reduce grain read timeout from 100ms to 20ms for tighter
loop with LWS poll
- node_runner: add 'status' command handler that sends node status
back via control server