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

Ensure compliant publisher API #210

Merged
merged 3 commits into from
Jul 28, 2020
Merged

Conversation

hidmic
Copy link
Contributor

@hidmic hidmic commented Jul 24, 2020

Precisely what the title says. Connected to ros2/rmw#252.

hidmic added 2 commits July 24, 2020 13:43
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
@hidmic hidmic requested review from eboasson and ivanpauno July 24, 2020 16:44
return destroy_publisher(publisher);

rmw_ret_t inner_ret = destroy_publisher(publisher);
if (RMW_RET_OK != inner_ret) {
Copy link
Contributor Author

@hidmic hidmic Jul 24, 2020

Choose a reason for hiding this comment

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

I don't like having to do this to ensure the first error that occurs is the one that pops up and that no subsequent error goes unnoticed.

If we had a way to tell rcutils that we're in error handling or finalization/cleanup mode so that it doesn't complain about error states being overwritten (and prints the new one to stderr, or aborts the program, or whatever), this code would simpler (and a bit more neat). What do reviewers think?

Copy link
Member

@ivanpauno ivanpauno Jul 24, 2020

Choose a reason for hiding this comment

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

The current logic isn't super nice, but isn't wrong either.
Maybe directly logging all destruction errors and setting a generic error state at the end is a better idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The current logic isn't super nice, but isn't wrong either.

No, it's not incorrect, but it's... messy.

Maybe directly logging all destruction errors and setting a generic error state at the end is a better idea.

We could do that, but that doesn't cover errors during cleanup. Besides, it's important to know what the actual error was to do something about it (or debug it), nevermind leaks. At any rate, I don't mind doing this. I just figured it'd much easier if rcutils took care of redirecting all RCUTILS_SET_ERROR_MSG() for a given scope. @clalancette @wjwwood @jacobperron for feedback too.

Copy link
Member

Choose a reason for hiding this comment

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

We could do that, but that doesn't cover errors during cleanup

Do you mean the cleanup that a function does when it fails?
In that case it would be good to set an error message about what failed, and log all cleanup failures.
So logging is fine in that case too,

I just figured it'd much easier if rcutils took care of redirecting all RCUTILS_SET_ERROR_MSG() for a given scope

How?

Copy link
Contributor Author

@hidmic hidmic Jul 24, 2020

Choose a reason for hiding this comment

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

For instance, having a flag in TLS that client code can toggle. For C++ implementations, we may be able to use RAII for easier control of the error handling scope. If done right it can reduce clutter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, that's fair. As I said elsewhere, I wonder about the usefulness of a return code if we log everything.

Copy link
Member

Choose a reason for hiding this comment

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

The return code would still be useful, as the caller can know that sth failed (it doesn't matter if we return the first error code or the last one).
The error string won't be useful if we log everything, yes.

Copy link
Member

Choose a reason for hiding this comment

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

I wonder about the usefulness of a return code if we log everything

Isn't the purpose of the return code so that the calling function knows something went wrong, and optionally if there is enough information in the return code to then make an intelligent decision about what to do about it? The logging is more for after-the-fact debugging so having everything logged doesn't seem bad to me.

Having an error string would also still be useful for when logging is turned down, I think.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not simply pass an RMW error state object around inside the implementation, with a setter that implements the behaviour of returning the first error and logging the rest? That's basically the pattern you have here with ret and inner_ret, but it'd remove the messiness from the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

and optionally if there is enough information in the return code to then make an intelligent decision about what to do about it?

IMHO that's the whole point of having different, documented return codes, vs. a bool.

Why not simply pass an RMW error state object around inside the implementation, with a setter that implements the behaviour of returning the first error and logging the rest?

Yeah, I was trying not to (re)build this behavior for each RMW implementation, but to make it widely available. I'll probably push this as-is until we've reached consensus on how to do this nicely.

@@ -1954,9 +1987,16 @@ extern "C" rmw_publisher_t * rmw_create_publisher(
static_cast<void *>(&msg),
nullptr))
{
rmw_error_state_t error_state = *rmw_get_error_state();
Copy link
Member

Choose a reason for hiding this comment

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

nit: Inverting the logic in L1978, setting an error message and returning NULL will make the logic a bit clearer.

return destroy_publisher(publisher);

rmw_ret_t inner_ret = destroy_publisher(publisher);
if (RMW_RET_OK != inner_ret) {
Copy link
Member

@ivanpauno ivanpauno Jul 24, 2020

Choose a reason for hiding this comment

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

The current logic isn't super nice, but isn't wrong either.
Maybe directly logging all destruction errors and setting a generic error state at the end is a better idea.

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.

It looks correct to me.

Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
@hidmic
Copy link
Contributor Author

hidmic commented Jul 27, 2020

CI up test_rmw_implementation against all RMW implementations:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

Copy link
Member

@ivanpauno ivanpauno left a comment

Choose a reason for hiding this comment

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

LGTM

@hidmic
Copy link
Contributor Author

hidmic commented Jul 28, 2020

Ok, CI's green and reviewers are happy. Going in!

@hidmic hidmic merged commit 2e2c6d1 into master Jul 28, 2020
@delete-merged-branch delete-merged-branch bot deleted the hidmic/compliant-publisher-impl branch July 28, 2020 21:47
@hidmic
Copy link
Contributor Author

hidmic commented Jul 28, 2020

Confirmed locally that this patch introduces no new leaks. valgrind does point out that we may be leaking through create_message_typesupport. We can follow-up in a separate PR.

ahcorde pushed a commit that referenced this pull request Oct 8, 2020
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
ahcorde pushed a commit that referenced this pull request Oct 15, 2020
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
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