Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[19942] Make remove unused entities compatible with the discovery trigger #83

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Tempate
Copy link
Contributor

@Tempate Tempate commented Jan 17, 2024

No description provided.

@codecov-commenter
Copy link

codecov-commenter commented Jan 17, 2024

Codecov Report

Attention: Patch coverage is 46.42857% with 60 lines in your changes are missing coverage. Please review.

Project coverage is 34.12%. Comparing base (8c96a74) to head (4428faa).

Files Patch % Lines
...spipe_core/src/cpp/communication/dds/DdsBridge.cpp 31.34% 36 Missing and 10 partials ⚠️
...core/src/cpp/configuration/RoutesConfiguration.cpp 70.96% 3 Missing and 6 partials ⚠️
ddspipe_core/src/cpp/core/DdsPipe.cpp 62.50% 2 Missing and 1 partial ⚠️
ddspipe_core/src/cpp/communication/dds/Track.cpp 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #83      +/-   ##
==========================================
+ Coverage   34.10%   34.12%   +0.01%     
==========================================
  Files         154      155       +1     
  Lines        7861     7881      +20     
  Branches     3515     3518       +3     
==========================================
+ Hits         2681     2689       +8     
- Misses       3267     3287      +20     
+ Partials     1913     1905       -8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Tempate Tempate changed the title Make remove unused entities compatible with the discovery trigger [19942] Make remove unused entities compatible with the discovery trigger Jan 29, 2024
ddspipe_core/include/ddspipe_core/core/DdsPipe.hpp Outdated Show resolved Hide resolved
{
writer_it.second->disable();
}
// Don't disable writers, as they may be used by other tracks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I agree this might make more sense, note that I believe this would imply a delayed abortion when stopping the pipe or blocking a topic (would keep looping through writers map until done). Also, I don't like the fact that this would make enable-disable asymmetrical.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not disabling the writers wasn't an aesthetic choice. If you disable the writers there are many scenarios that don't work or segfault with discovery-trigger and remove-unused-entities. If you propose another solution I may consider it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment was wrong, not disabling writers has no effect in how soon Track::transmit_ is aborted. After thinking about it, I prefer to leave it as it is: having "atomic" write operations for every taken data.

However, I still don't like the asymmetry. I propose:

  • Leave it as it is but with a nice comment for future developers to consider.
  • Do not enable writers in tracks' enable, create them always enabled and never disable, or handle enable/disable somewhere else (in DdsBridge for example, as long as we decide to keep the writers_ attribute).

ddspipe_core/src/cpp/communication/dds/DdsBridge.cpp Outdated Show resolved Hide resolved
ddspipe_core/src/cpp/communication/dds/DdsBridge.cpp Outdated Show resolved Hide resolved
@Tempate Tempate force-pushed the feature/dynamic_tracks_discovery_trigger branch from 6abb4d6 to 1cf2453 Compare July 15, 2024 14:27
std::map<types::ParticipantId, std::unique_ptr<Track>> tracks_;

//! The writers of the bridge index by their participant_id.
std::map<types::ParticipantId, std::shared_ptr<IWriter>> writers_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design comment: up to now bridges contain tracks, and tracks the only ones holding reference to endpoints. Analyze implications (such as object lifespan) and try to maintain this principle if makes sense.

}
}
else if (configuration_.remove_unused_entities && topic->topic_discoverer() != DEFAULT_PARTICIPANT_ID)
{
// The bridge already exists. Create a writer in the participant who discovered it.
it_bridge->second->create_writer(topic->topic_discoverer());
it_bridge->second->create_endpoint(topic->topic_discoverer(), endpoint_kind);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design comment: call to endpoint creation method is done both from pipe and bridge. Analyze if it would be possible to further isolate their functionality so it's only done from one of them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related: scope of remove_unused_endpoint (used both in pipe and bridge).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Piggyback: please add a comment explaining that comparison with DEFAULT_PARTICIPANT_ID is used to determine whether topics are builtin.

{
writer_it.second->disable();
}
// Don't disable writers, as they may be used by other tracks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment was wrong, not disabling writers has no effect in how soon Track::transmit_ is aborted. After thinking about it, I prefer to leave it as it is: having "atomic" write operations for every taken data.

However, I still don't like the asymmetry. I propose:

  • Leave it as it is but with a nice comment for future developers to consider.
  • Do not enable writers in tracks' enable, create them always enabled and never disable, or handle enable/disable somewhere else (in DdsBridge for example, as long as we decide to keep the writers_ attribute).

Copy link
Contributor

@juanlofer-eprosima juanlofer-eprosima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Piggyback request:

Please add to the participant's discovery traces the participant id (missing in endpoint removed/ignored/changed qos cases), I believe this is quite helpful for debugging.

* @param routes_config: Configuration of the routes of the Bridge
* @param remove_unused_entities: Whether the Bridge should remove unused entities
* @param manual_topics: Topics that explicitally set a QoS attribute for this participant
* @param endpoint_kind: Kind of the endpoint that discovered the topic
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: I believe DdsBridge should be agnostic (or at least has been until now) to discovery events. So instead of passing the kind of the endpoint that discovered the topic or was discovered, I would pass the kind of the endpoint that should be created.

@@ -527,7 +531,8 @@ void DdsPipe::create_new_service_nts_(
}

void DdsPipe::activate_topic_nts_(
const utils::Heritable<DistributedTopic>& topic) noexcept
const utils::Heritable<DistributedTopic>& topic,
const EndpointKind& endpoint_kind /*= EndpointKind::reader*/) noexcept
Copy link
Contributor

@juanlofer-eprosima juanlofer-eprosima Jul 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be careful with the following case: an endpoint is discovered while its topic is blocked, then it is only added to current_topics_ hence losing the kind information. So if the topic is then allowed, a bridge is wrongly created with the default kind value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related scenario: subsequent relevant discovered endpoints would not be taken into account, but only the first one (used in DdsBridge constructor).

Copy link
Contributor

@juanlofer-eprosima juanlofer-eprosima Jul 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential solution: create an EndpointsManager that would keep track of all created endpoints, and also the ones that should be created once enabled (so DdsBridges will always be created even if the topic is disabled). This new object would then contain all references of entities, so the creation of a track would require passing a reference to this object as well as a map of ids.

// Add the writer to the tracks it has routes for.
add_writer_to_tracks_nts_(participant_id, writer);
// Create the track
create_track_nts_(participant_id, reader, writers_);
Copy link
Contributor

@juanlofer-eprosima juanlofer-eprosima Jul 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't you be passing only the IWriters in the route?

assert(participant_id != DEFAULT_PARTICIPANT_ID);

// Create the writer
auto writer = create_writer_nts_(participant_id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another corner case: shouldn't we avoid creating writers if not present in any route?

Copy link
Contributor

@juanlofer-eprosima juanlofer-eprosima Jul 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related: should we also avoid creating a reader if there is a "blockage" route? I'd say yes.

RoutesConfiguration::RoutesMap RoutesConfiguration::routes_of_readers(
const std::map<types::ParticipantId, bool>& participant_ids) const noexcept
{
static RoutesConfiguration::RoutesMap readers_routes;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove static.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants