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

refactor init to allow options to be passed and to not be global #154

Merged
merged 4 commits into from
Nov 30, 2018

Conversation

wjwwood
Copy link
Member

@wjwwood wjwwood commented Nov 6, 2018

tl;dr I would like reviews of the proposed changes to this API while I finish refactoring things up and down the stack to use this new API. So it's ready for review, but not for CI nor merge.


This pull request is motivated by new rmw implementations that require additional configuration during initialization.

This pull request makes two major changes:

  • it allows for options to be passed to rmw_init() and then be accessed via a returned rmw_init_context_t instance, and
  • the rmw_init_context_t allows rmw_init() to be non-global

This also:

  • actually adds rmw_shutdown() (previously referenced in documentation but never implemented)
  • changes the rmw_create_node() and rmw_create_guard_condition() functions to take the rmw_init_context_t as an argument, so they do not need to access global variables

I explicitly avoided refactoring rmw_create_node() to return a ret value rather than the pointer (so you can get more discrete error reasons) so I can do that when refactoring these interfaces to take allocators. I added a TODO in the meantime.

@wjwwood wjwwood added enhancement New feature or request in review Waiting for review (Kanban column) labels Nov 6, 2018
@wjwwood wjwwood self-assigned this Nov 6, 2018
@Karsten1987
Copy link
Contributor

This generally looks good to me (afaict). I like the idea of not having rmw_init() as global.

Just a few things which came to my mind here:

  • if context or init_options are implementation dependent, I believe it makes sense to add the rmw identifier to it.
  • if the idea is to access the init options from the context object, what's the difference between the two data types? Is context a superset of init_options then?
  • I wonder whether it makes sense to have these data types as generic key-value pairs which might be written to disk (a.k.a rosbags) to have a consistent environment when replaying data. But that's just an idea as I don't really know what kind of options you're thinking about here. You could also come around that later by having maybe a serialization function for them.

@wjwwood
Copy link
Member Author

wjwwood commented Nov 7, 2018

Thanks for the feedback.

  • if context or init_options are implementation dependent, I believe it makes sense to add the rmw identifier to it.

That's a good idea. I'll do that.

  • if the idea is to access the init options from the context object, what's the difference between the two data types? Is context a superset of init_options then?

There is overlap between the two types, but neither is necessarily a superset of the other. I could choose to include the entire options structure in the context just for potential use in the future, but that's not necessary.

For example, imagine an option like "do_not_register_signal_handlers", which is useful during init, but not necessarily afterwards, so it might not make it into the context by itself. But an option like instance_id is potentially needed to do initialization and should end up in the context for later use, so it has to be in the options, and so it exists in both.

  • I wonder whether it makes sense to have these data types as generic key-value pairs which might be written to disk (a.k.a rosbags) to have a consistent environment when replaying data. But that's just an idea as I don't really know what kind of options you're thinking about here. You could also come around that later by having maybe a serialization function for them.

I don't think that's in scope here. Also these settings will probably not influence things like node names, topic names, etc., and so I'm not sure how important they are to playback.

I think the key-value pairs might work for the options, but would be very efficient for accessing elements of the context.

On the other hand, I don't think the key-value pair makes it possible to serialize them somehow where it was impossible before. So I think I'd pass on this for now.

rmw/include/rmw/init.h Outdated Show resolved Hide resolved
@dirk-thomas
Copy link
Member

👍 to rmw_init_context_t enabling to encapsulate state through the lifetime of an rmw between init and shutdown. For the layers above rmw it is a blackbox for passing state between rmw function calls. I would suggest to drop the init part from the name since it seems to provide context beyond just the initialization.

Regarding the rmw_init_options_t I am not sure I understand the purpose fully. Since the actual options in the strict are rmw implementation specific (do I understand that correctly?) how can the caller make use of any of this if using the generic rmw interface without locking itself to a specific implementation?

@wjwwood
Copy link
Member Author

wjwwood commented Nov 8, 2018

I would suggest to drop the init part from the name since it seems to provide context beyond just the initialization.

Ok. My thinking was that there was one context per init, that's why I left init in the name. I thought of it like the init handle is analogous to the node handle or something like that. But I don't feel strongly about it, I'll drop the init.

how can the caller make use of any of this if using the generic rmw interface without locking itself to a specific implementation?

Well they cannot, but the idea for now was that an rmw specific function could be used to "mutate" the implementation specific init options before passing them into the init. Doing so will tie you to a specific implementation.

What this does enable, however, is to have code in the implementation of rmw_init() that can do different things based on the options without relying on global state.

In the future, we might come up with a way to declare which ROS primitives you're going to create at the start (storing them in the init options) and then pass that to init, but not right now. This was talked about here:

#126

@dirk-thomas
Copy link
Member

Well they cannot, but the idea for now was that an rmw specific function could be used to "mutate" the implementation specific init options before passing them into the init. Doing so will tie you to a specific implementation.

Thanks for clarifying. Sounds good to me. I just wanted to check I understood it correctly. Maybe adding a note in the docblock would be good - just to avoid users being unsure how to set options if they are not aware that it only works for rmw specific implementation?

Copy link
Member

@jacobperron jacobperron left a comment

Choose a reason for hiding this comment

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

LGTM

* \return `RMW_RET_OK` if the copy is successful, or
* \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if the implementation
* identifier for src does not match the implementation of this function, or
* \return `RMW_RET_INVALID_ARGUMENT` if the dst has already be initialized, or
Copy link
Member

Choose a reason for hiding this comment

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

Consider adding another type: RMW_RET_OPTIONS_ALREADY_INIT

@gonzodepedro
Copy link

LGTM

@wjwwood
Copy link
Member Author

wjwwood commented Nov 30, 2018

CI:

  • Linux Build Status
  • Linux (OpenSplice) Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@wjwwood
Copy link
Member Author

wjwwood commented Nov 30, 2018

The two warnings on macOS are unrelated to my changes, so I'm going to merge! 🎉

@wjwwood wjwwood merged commit 4882850 into master Nov 30, 2018
@wjwwood wjwwood deleted the refactor_init branch November 30, 2018 05:32
@wjwwood wjwwood removed the in review Waiting for review (Kanban column) label Nov 30, 2018
@dirk-thomas
Copy link
Member

The two warnings on macOS are unrelated to my changes

The two new warning are caused by changes in ros2/rcl#336. Also in the latest packaging job: https://ci.ros2.org/job/ci_packaging_osx/59/warnings11Result/ The patch introduced new member to existing structs hence the initialization of these structs needs to be updated to initialize one more member.

@wjwwood
Copy link
Member Author

wjwwood commented Nov 30, 2018

Ok, you're right, I assumed that the statement was unaffected by me because in C {0} is supposed to initialize the whole struct. I thought it must have been a change to how the code was being compiled as part of other changes. Also I remember a pr from @sloretz about removing clang warnings which I associated with this.

I'll fix it asap.

@wjwwood
Copy link
Member Author

wjwwood commented Nov 30, 2018

See ros2/rcl#345, interestingly I don't see this warning on my macbook...

dabonnie pushed a commit to aws-ros-dev/rmw that referenced this pull request Apr 2, 2019
…2#154)

* refactor init to allow options to be passed and to not be global

Signed-off-by: William Woodall <[email protected]>

* use implementation identifier in init and shutdown functions

Signed-off-by: William Woodall <[email protected]>

* refactors and renames

Signed-off-by: William Woodall <[email protected]>

* refactor init_options into its own files

Signed-off-by: William Woodall <[email protected]>
Signed-off-by: Devin Bonnie <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants