Skip to content

Merge pipeline architecture improvements #260

@bburda

Description

@bburda

Summary

Several architecture improvements for the merge pipeline to reduce lock contention, improve extensibility, and fix subtle merge semantics.


Proposed solution (optional)

1. Double-buffering for HybridDiscovery mutex

HybridDiscoveryStrategy::refresh() holds the mutex during the entire pipeline_.execute() call, which includes synchronous ROS 2 graph introspection. All HTTP handlers calling discover_*() block during refresh, causing request latency spikes.

File: src/ros2_medkit_gateway/src/discovery/hybrid_discovery.cpp:48-55

Fix: Execute pipeline without lock, then swap result under lock.

2. Replace dynamic_cast for RuntimeLayer statistics

MergePipeline::execute() uses dynamic_cast<RuntimeLayer*> to get last_filtered_count(). This couples the pipeline to a concrete type, violating OCP.

File: src/ros2_medkit_gateway/src/discovery/merge_pipeline.cpp:418

Fix: Add virtual size_t filtered_count() const { return 0; } to DiscoveryLayer base class.

3. Fix merge_bool sticky OR for external field

merge_bool() uses target = target || source for MergeWinner::BOTH. Once any layer sets a boolean to true, it can never be reverted. Correct for is_online but wrong for external.

File: src/ros2_medkit_gateway/src/discovery/merge_pipeline.cpp:89-103

Fix: Move external to METADATA field group where manifest is AUTHORITATIVE by default.

4. Make MergePipeline accessors private

get_last_report() and get_linking_result() are public but only called through HybridDiscoveryStrategy. Direct calls would be a data race (no internal mutex).

File: src/ros2_medkit_gateway/include/ros2_medkit_gateway/discovery/merge_pipeline.hpp:67-85

Fix: Make them private with friend class HybridDiscoveryStrategy.


Additional context (optional)

Found during self-review of PR #258. Item 1 (mutex contention) is the most impactful for production - it affects request latency during every discovery refresh cycle.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions