-
Notifications
You must be signed in to change notification settings - Fork 75
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
Replace existing RealtimeBox implementation with RealtimeBoxBestEffort implementation #146
base: master
Are you sure you want to change the base?
Conversation
…meBox, enable/disable certain methods for pointer types, Box is now usable for pointer types
…tests into a single file and adapted the naming of the existing tests for the RealtimeBox
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #146 +/- ##
=======================================
Coverage 75.36% 75.36%
=======================================
Files 8 7 -1
Lines 341 341
Branches 62 62
=======================================
Hits 257 257
Misses 50 50
Partials 34 34
Flags with carried forward coverage won't be shown. Click here to find out more.
|
@christophfroehlich I will update this PR as soon as #139 is finished |
Fixes #138 |
@christophfroehlich Given that #139 is now merged I updated this PR. Also pinging @saikishor |
@christophfroehlich Just a note about the CI. Interestingly I just had the case that pre-commit in the CI failed but did run sucessfully on my system. (Note about using the right include guard - REALTIME_TOOLS__REALTIME_BOX_H_) |
Yes that's what I did run. But I couldn't reproduce it now. . |
We don't have a RST documentation of this repo, but I plan to rework the API documentation somewhen on control.ros.org. For now, please just add anything in the manner of rosdoc2 to be published on index.ros.org |
Is there a way to add some methods with old pointers and deprecation warnings? |
if this is not possible, I don't think it is nice to completely override it and force everyone to change. If we want this to be the default implementation, then we would need to add a deprecation message to the old one and ask everyone to switch to the new one. |
The current implementation in the RealTimeBoxBestEffort basically disables the normal Given that it is inherently unsafe to use pointers with this implemenation and the default Nevertheless I completely understand your argument. I guess adding a deprecation notice might be possible but I am not sure what is the best way at the moment. We could use SFINEA to provide a version of the class for pointers that include the deprecation notices (and removes the In the end I think this really comes to the question: Allow wrong behavior or possibly break builds? |
I already agree with you on the unsafe part from the other PR, the problem here is we have a single branch that runs for Rolling, Iron, and also Humble, so breaking it would be breaking the setup of a lot of users, and such API breaking is usually not seen good. I could think of the following 3 options:
What do you think about this? |
This introduces additional maintenance effort -> I can not judge if this would be worth the effort
According to https://stackoverflow.com/questions/48045559/how-do-i-declare-sfinae-class I could do that. I am currently trying to figure out a way to do this
This does not solve the problem. As the aim of this implementation is to provide thread safe access to its contents the access to any pointer type has to be wrapped in the way shown in the examples. (Using the shared_ptr does not make it safer than using a raw pointer) |
@saikishor I just pushed a version which add a specialisation for pointer types. The tests will now show a deprecation note if get/set are used with pointer types. Also the code starts looking like a stl class...not sure if thats a good thing :D |
Please just add another line to the copyright claim and don't remove the old one if old code remained inside (at least I saw this in other ROS repos) |
@saikishor Perhaps you'll find some time for another review? It will now handle pointers types as before but print a deprecation warning |
Just a friendly ping :) |
* @return false if the mutex could not be locked | ||
* @note only safe way to access pointer type content (rw) | ||
*/ | ||
bool trySet(const std::function<void(T &)> & func) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool trySet(const std::function<void(T &)> & func) | |
bool try_set(const std::function<void(T &)> & func) |
we've been following snake-case in ros2_control, please adjust the rest too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest I am a bit puzzled about this comment given that the PR that introduced these names was accepted #139
This PR ist just for replacing the old RealtimeBox with the new implementation while still keeping it backward compatible with the corresponding deprecation warnings.
Btw. @christophfroehlich As far as I know it is possible with clang-tidy to enforce such code styles. Perhaps you might want to look into that :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@firesurfer few minor comments.
Thank you and sorry for the huge delay
template <class T, typename mutex_type> | ||
class RealtimeBox<T, mutex_type, true> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
template <class T, typename mutex_type> | |
class RealtimeBox<T, mutex_type, true> | |
template <class T, typename mutex_type> | |
[[deprecated("RealtimeBox is not recommended to use with Raw pointers! Use smart pointers instead.")]] | |
class RealtimeBox<T, mutex_type, true> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should actually be: Only use the "get/set(std::function) overloads of the RealtimeBox (which is the reason why we added this template specialisation for pointers).
But that deprecation message is already printed when the default get/set methods are used with pointers!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it wiser to mark the class as deprecated?, as you know from the beginning that type is not supported
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps I should give a quick recap why it is designed like this given that quite some time has passed now:
-
The existing RealtimeBox implementation is not safe to use with any kind of pointer. Because only any operation on the pointer itself would be locked by the mutex but not the access to the data behind the pointer
-
The RealtimeBoxBestEffort solves this issue by providing additional overloads to get/set which take a function. These overloads lock the mutex and call the function. Inside this function manipulating the pointer is safe.
Additionally if the Type is a pointer the normal get/set methods which return a reference to the internal value are disabled via SFINEA (std::enable_if) -
It makes sense to replace the existing RealtimeBox with the RealtimeBoxBestEffort (This is what this PR aims for). Additionally the requirement was made: We shall not break existing code, but we want to display deprecation notices if the default get/set methods are used with pointers. Therefore I added a template specialisation for pointers removes the std::enable_if for get/set with pointer types and adds deprecation notices for the get/set methods without the std::function overloads.
This should encourage users to migrate to the get/set(std::function) version for pointer types.
So in a future release the pointer specialisation of the class can be removed.
So to answer your question:
Pointer types are supported BUT you need to use the get/set(std::function) methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@firesurfer I understand your point. What I'm saying is, we don't have to break the Raw pointer in this version, but in the future versions, we can make the users use the smart pointers. So, if we mark the class deprecated with the notice to use the smart pointers in future releases, the users will be able to migrate in the meantime.
If we mark the methods alone, they still think the Raw pointers will be supported in the future. I'm not sure, if it is interesting to support Raw pointer in the future. If we still want to support, then the way you marked the depreciation is good enough @bmagyar @christophfroehlich any comments on this?
* the value behind the pointer | ||
*/ | ||
template <class T, typename mutex_type> | ||
class RealtimeBox<T, mutex_type, true> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@firesurfer In this overlayed class, do we need to have a copy of most of the methods similar to the previous one? or is there a way to reuse them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@saikishor From the "base" implementation:
// Provide a specialisation for non pointer types
// NOTE: When migrating to a safe access only version just remove the specialisation for pointer
// and let this be the only version!
My argument would be that in the longterm the pointer specialisation should be removed. I think the only save way to access the values behind pointers is to use the "get/set(std::function) overloads).
By keeping the code duplicated we can simplify this process.
My suggestion is to keep this version for at least one release and remove the pointer specialisation in the next one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm! @bmagyar @christophfroehlich any strong opinion on this one?
// This does not and should not compile! | ||
// auto value = box.get(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// This does not and should not compile! | |
// auto value = box.get(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment this would compile btw. (Because we added the pointer specialisation for compatibility reasons)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, then let's remove the comment.
Co-authored-by: Sai Kishor Kothakota <[email protected]>
Hi as said in #139 this PR replaces the existing RealtimeBox implementation with the new implementation provided in #139 . I merged the tests into a single file and they work fine (even though the existing implementation had only a very small amount of tests)
The implementation of the get/set methods matches exactly the one from the existing implementation apart from some template magic which disables the standard get/set methods for pointer types. (For which they wouldnt provide any thread safety btw from my point of view - see #138)
TLDR: Merging this has the potential to break existing code if someone used pointer types with the RealtimeBox. For everything else it should work just fine.
I would also be happy to provide some documentation on how to use this implementation but I am not sure where in the repository it should go.
This PR should be merged after #139
EDIT: One question regarding the copyright notice for the existing tests. How should this be handled? At the moment I didn't copy any of it to the merged file.