-
Notifications
You must be signed in to change notification settings - Fork 110
Support BOOST_ASIO_NO_TS_EXECUTORS #830
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
Conversation
This fixes #829 |
Now, I accepted CI run. It requires for the first time contribution. I think that the PR is not tested by CI. mqtt_cpp/.github/workflows/gha.yml Line 80 in 117155f
The parallel builds are limited by the Github Actions. So I picked up some of typical case based on orthogonal array. In order to use BOOST_ASIO_NO_TS_EXECUTORS, maybe boost should be updated. mqtt_cpp/.github/depends/boost.sh Lines 36 to 39 in 117155f
mqtt_cpp/.github/workflows/gha.yml Line 59 in 117155f
Could you update CI ? |
Codecov Report
@@ Coverage Diff @@
## master #830 +/- ##
=======================================
Coverage 80.91% 80.92%
=======================================
Files 62 62
Lines 9223 9226 +3
=======================================
+ Hits 7463 7466 +3
Misses 1760 1760 |
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 is the first review.
I will add some of new review comments after the first review would finish.
include/mqtt/sync_client.hpp
Outdated
friend std::shared_ptr<callable_overlay<sync_client<tcp_endpoint<as::ip::tcp::socket, | ||
#if defined(MQTT_NO_TS_EXECUTORS) | ||
as::io_context::executor_type | ||
#else | ||
null_strand | ||
#endif | ||
>>>> |
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.
null_strand is a kind of null object pattern.
If has the same interface as strand but do nothing.
So if user wants to use mqtt_cpp on single thread without locks, the user can use it.
What happens as::io_context::executor_type ?
Does this work as null_strand?
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.
Could you use the following coding style for multi line template ?
mqtt_cpp/include/mqtt/v5_message.hpp
Lines 546 to 552 in 117155f
template < | |
typename ConstBufferSequence, | |
typename std::enable_if< | |
as::is_const_buffer_sequence<ConstBufferSequence>::value, | |
std::nullptr_t | |
>::type = nullptr | |
> |
See also https://github.com/redboltz/mqtt_cpp/wiki/Coding-Rules
In this case, please use the following indent.
friend std::shared_ptr<
callable_overlay<
sync_client<
tcp_endpoint<
as::ip::tcp::socket,
#if defined(MQTT_NO_TS_EXECUTORS)
as::io_context::executor_type
#else
null_strand
#endif
>
>
>
>
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.
Sorry, I missed the part about template indention in the Coding Guidelines.
I'll update my code accordingly.
The proposed standard executor style of Asio provides executors per context that can be copied and modified to track outstanding work - not exit ctx.run()
when nothing has been queued - for example.
The as::io_context::executor_type
contains a pointer to the context it is associated with.
Like this it works the same as null_strand did before but uses a copy of the ctx.get_executor()
directly instead of going through an additional object.
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.
Sorry, I missed the part about template indention in the Coding Guidelines.
I updated the wiki after you post the PR. So you didn't miss anything at that time :)
I'll update my code accordingly.
Thank you.
The proposed standard executor style of Asio provides executors per context that can be copied and modified to track outstanding work - not exit
ctx.run()
when nothing has been queued - for example.
Theas::io_context::executor_type
contains a pointer to the context it is associated with.
Like this it works the same as null_strand did before but uses a copy of thectx.get_executor()
directly instead of going through an additional object.
Good to know. I understand that the proposed standard version already has null_strand like mechanism.
Thanks for the feedback. About updating the boost version: mqtt_cpp/.github/workflows/gha.yml Line 59 in 117155f
Is there any specific pattern in the date part of the cache key 20200107? Do you want me to add any specific date - e.g. boost verion's release date? Or should it just be the commit date 20210816? |
I guess that you need to implement parameter passing code.
I don't know much about cache mechanisim. |
Maybe security reason, the first time contributor for the project like you cannot run CI automatically. You can also run CI on your github account. If you want to test CI with quick turn around time, you can use it. |
include/mqtt/async_client.hpp
Outdated
#if defined(MQTT_NO_TS_EXECUTORS) | ||
as::strand<as::io_context::executor_type> | ||
#else | ||
as::io_context::strand | ||
#endif |
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.
#if defined(MQTT_NO_TS_EXECUTORS) | |
as::strand<as::io_context::executor_type> | |
#else | |
as::io_context::strand | |
#endif | |
MQTT_STRAND |
And introduce the new header file strand.hpp
and include it.
// Include and header comment like other header files....
#if defined(MQTT_NO_TS_EXECUTORS)
#define MQTT_STRAND as::strand<as::io_context::executor_type>
#else // defined(MQTT_NO_TS_EXECUTORS)
#define MQTT_STRAND as::io_context::strand
#endif // defined(MQTT_NO_TS_EXECUTORS)
I want to avoid #if defined
code repetition.
include/mqtt/async_client.hpp
Outdated
#if defined(MQTT_NO_TS_EXECUTORS) | ||
as::io_context::executor_type | ||
#else | ||
null_strand | ||
#endif |
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.
#if defined(MQTT_NO_TS_EXECUTORS) | |
as::io_context::executor_type | |
#else | |
null_strand | |
#endif | |
MQTT_NULL_STRAND |
And int the header file strand.hpp, add the following macro.
// Include and header comment like other header files....
#if defined(MQTT_NO_TS_EXECUTORS)
#define MQTT_NULL_STRAND as::io_context::executor_type
#else // defined(MQTT_NO_TS_EXECUTORS)
#define MQTT_NULL_STRAND null_strand
#endif // defined(MQTT_NO_TS_EXECUTORS)
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.
That makes perfect sense.
Would you like me to define MQTT_STRAND and MQTT_NULL_STRAND both in strand.hpp
?
Or should MQTT_NULL_STRAND be defined in null_strand.hpp
?
#if !defined(MQTT_NULL_STRAND_HPP)
#define MQTT_NULL_STRAND_HPP
#if defined(MQTT_NO_TS_EXECUTORS)
#define MQTT_NULL_STRAND as::io_context::executor_type
#else // defined(MQTT_NO_TS_EXECUTORS)
// null_strand code as is
#define MQTT_NULL_STRAND null_strand
#endif // defined(MQTT_NO_TS_EXECUTORS)
#endif // MQTT_NULL_STRAND_HPP
It seems awkward to
#define MQTT_NULL_STRAND null_strand
in strand.hpp
but also have a conditional include in client.hpp
and server.hpp
.
#if !defined(MQTT_NO_TS_EXECUTORS)
#include <mqtt/null_strand.hpp>
#endif
Please share your thoughts.
I'll try setup CI runs on my account for now and change the branch to avoid triggering CI here until it works. |
In order to run CI on your github account, I recommend modifying as follows: https://github.com/redboltz/mqtt_cpp/blob/master/.github/workflows/gha.yml#L8 Before on:
pull_request:
types: [opened, synchronize]
push:
branches:
- master
tags:
- '*' After (for only temporary) on:
pull_request:
types: [opened, synchronize]
push:
branches:
- '*'
tags:
- '*' When you push something, the CI always run. You can see CI on the top "Actions" menu. Azure build pilelines is different from Github Actions. It is more complicated. I think that you don't need to run it. |
Changes are in. The CI is supposed to test MQTT_NO_TS_EXECUTORS as part of the test you selected (linux 4) which passed on my CI. |
|
It seems that CI has been passed and codecov reported a coverage. The result is good. So I merge it soon. |
Merged. @DinoMe , thank you for your contribution !! |
Great. @redboltz, thanks a lot for merging and accepting my changes. |
This adds support for using Boost Asio with BOOST_ASIO_NO_TS_EXECUTORS being defined.
It adds a preprocessor definition MQTT_NO_TS_EXECUTORS to determine which executor style to use.
This is present as a CMake option as well.
The preprocessor argument is either defined by CMake or is forced in case BOOST_ASIO_NO_TS_EXECUTORS have been defined w/out MQTT_NO_TS_EXECUTORS - see addition to mqtt/config.hpp.
Thus mqtt_cpp code will still be compliant even if the user did not explicitly enable the CMake option.
Even though a CMake option has been added, the CI tests have not been modified.
Hence automatic testing does not include MQTT_NO_TS_EXECUTORS yet.
If this is to be added to the tests on the CI, boost.sh would also have to be modified.
It currently builds Boost 1.72.0 but at least 1.74.0 / Asio 1.18.0 is required to use the standard executors.