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

Implement matched event #435

Merged

Conversation

Barry-Xu-2018
Copy link
Contributor

Address ros2/rmw#330

Comment on lines 345 to 347
rmw_event_callback_t event_callback[RMW_EVENT_INVALID + 1] {nullptr};
const void * event_data[RMW_EVENT_INVALID + 1] {nullptr};
size_t event_unread_count[RMW_EVENT_INVALID + 1] {0};
Copy link
Contributor

Choose a reason for hiding this comment

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

these changes are required because there are two different events for matched and unmatched, right? (ros2/rmw_fastrtps#645 (comment))
I understand that different events can avoid user to do the further work to see which event comes in, but also we are providing the almost same event in the implementation...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

these changes are required because there are two different events for matched and unmatched, right? (ros2/rmw_fastrtps#645 (comment))

Yes. Original code is based on DDS_STATUS_ID which only matched event.
So in order to support unmatched event, I changed it to use RMW_EVENT ID.

I understand that different events can avoid user to do the further work to see which event comes in, but also we are providing the almost same event in the implementation...

rmw_take_event() will take event status from last read.
Now we use 2 RMW events for one DDS event, so we have to save the status of DDS event for each RMW event.

I discussed with Chen-san. Now we only know one real case. While first matched event (for subscription or publisher) happen, start certain service. While the last subscription or publisher is disconnected, stop certain service.

For this case, user will do based on matched/unmatched event

  • While RMW_EVENT_PUBLICATION_MATCHED/RMW_EVENT_SUBSCRIPTION_MATCHED is triggered, user check service is started. If not, start this service. Or call rmw_take_event() to check if current_matched_count is 1 and start service if count is 1.
  • While RMW_EVENT_PUBLICATION_UNMATCHED/RMW_EVENT_SUBSCRIPTION_UNMATCHED is triggered, user need to call rmw_take_event() to check if current_matched_count is 0. If count is 0, stop service.

If only one matched event (Same as DDS), user do the same thing as above.
Using 2 events doesn't bring convenience for user.

If user only care matched and unmatched event, current 2 events implementation can bring convenience.
2 events implementation introduce extra logic to rmw layer. I think ros2/rmw_fastrtps#645 (comment) don't want to have extra logic in rmw layer.
I have no enough requirement from real cases. Which implementation (2 events or 1 event) is better one.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I have no enough requirement from real cases.

That makes two of us ...

I would even go further: if the only foreseen use is starting/stopping a service, you could also simply do that based on a single event that merely says something changed in the set of matched readers. You use that event as a trigger, and then check that discovery information/graph cache to see whether you just went from 0 to 1 or from 1 to 0.

At least in this RMW layer, a quick reading of the changes suggests the code (almost) duplication could be eliminated by adding a few functions with well-chosen parameters.

Copy link
Contributor

Choose a reason for hiding this comment

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

@eboasson thanks for the comment!
CC: @Barry-Xu-2018

yeah, that is correct. i mean, we can just generate the event that tells us something happened on either publisher or subscription, then we can internally calls graph interfaces to return the number of endpoints. I would think most likely that works for many use cases.

one thing that i want to hear is there will be time window between triggering event from implementation and getting the graph information. these cannot be synced, so there might be event but it does not show any difference the graph change? this cannot be supported in current interfaces w/o this one?

Copy link
Collaborator

Choose a reason for hiding this comment

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

these cannot be synced, so there might be event but it does not show any difference the graph change? this cannot be supported in current interfaces w/o this one?

I would think so. If you need that information, then you do need something like this.

RMW_CHECK_ARGUMENT_FOR_NULL(rmw_event, RMW_RET_INVALID_ARGUMENT);

Copy link
Contributor

Choose a reason for hiding this comment

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

unrelated change should be avoided?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Will remove.

static inline rmw_event_type_t dds_event_to_rmw_event(
dds_status_id_t rmw_event,
const void * status,
user_callback_data_t * data)
Copy link
Contributor

Choose a reason for hiding this comment

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

is this actually needed as argument?

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 used.
This is residual code.


if (callback && data->event_unread_count[rmw_event->event_type]) {
// Push events happened before having assigned a callback
callback(user_data, data->event_unread_count[rmw_event->event_type]);
Copy link
Contributor

Choose a reason for hiding this comment

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

This will notify the user application matched/unmatched event that happened before? I am not sure if this is what user expects? probably user application is not interested in the events in the past for this case?

at least, we would want to have the same behavior for rmw implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes.
But for fastrtps, only matched/unmatched event don't notify previoius status. Other event will do.
So for keeping the same behavior, we have to deal with matched/unmatched individually.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Need to add below codes only for matched/unmatched event

  switch (rmw_event->event_type) {
    case RMW_EVENT_SUBSCRIPTION_MATCHED:
      data->event_unread_count[RMW_EVENT_SUBSCRIPTION_MATCHED] = 0;
      break;
    case RMW_EVENT_SUBSCRIPTION_UNMATCHED:
      data->event_unread_count[RMW_EVENT_SUBSCRIPTION_UNMATCHED] = 0;
      break;
    case RMW_EVENT_PUBLICATION_MATCHED:
      data->event_unread_count[RMW_EVENT_PUBLICATION_MATCHED] = 0;
      break;
    case RMW_EVENT_PUBLICATION_UNMATCHED:
      data->event_unread_count[RMW_EVENT_PUBLICATION_UNMATCHED] = 0;
      break;
    default:
      break;
  }

@fujitatomoya
Copy link
Contributor

@eboasson we would like to request the review on this.

this is related to new feature, ros2/rmw#330 (comment)

Copy link
Collaborator

@eboasson eboasson left a comment

Choose a reason for hiding this comment

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

I think this'll do what it says on the tin 🙂

Comment on lines 345 to 347
rmw_event_callback_t event_callback[RMW_EVENT_INVALID + 1] {nullptr};
const void * event_data[RMW_EVENT_INVALID + 1] {nullptr};
size_t event_unread_count[RMW_EVENT_INVALID + 1] {0};
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have no enough requirement from real cases.

That makes two of us ...

I would even go further: if the only foreseen use is starting/stopping a service, you could also simply do that based on a single event that merely says something changed in the set of matched readers. You use that event as a trigger, and then check that discovery information/graph cache to see whether you just went from 0 to 1 or from 1 to 0.

At least in this RMW layer, a quick reading of the changes suggests the code (almost) duplication could be eliminated by adding a few functions with well-chosen parameters.

@fujitatomoya
Copy link
Contributor

lgtm on my side.

Signed-off-by: Barry Xu <barry.xu@sony.com>
@mjcarroll
Copy link
Member

@Barry-Xu-2018 this has some conflicts now

@Barry-Xu-2018
Copy link
Contributor Author

Now interface is changed. We only use matched event in rmw layer (ros2/rmw#331).
So code changes are quite significant.
Besides, merged implementation of inconsistent topic leads to many conflicts with old commits while doing rebase.
So I will merge all commits in this PR to one commit and then do rebase.

@Barry-Xu-2018 Barry-Xu-2018 force-pushed the topic-add-match-unmatch-event-support branch from 054bca7 to df5e2f0 Compare March 16, 2023 09:48
@Barry-Xu-2018
Copy link
Contributor Author

Check failure is because rmw package is old in CI environment.

@Barry-Xu-2018 Barry-Xu-2018 changed the title Add matched/unmatched event support Implement matched event Mar 16, 2023
Signed-off-by: Barry Xu <barry.xu@sony.com>
@mjcarroll mjcarroll merged commit f6059c3 into ros2:rolling Mar 22, 2023
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.

5 participants