-
Notifications
You must be signed in to change notification settings - Fork 110
Use virtual functions for notifications from mqtt_cpp::endpoint to other code, instead of multiple std::functions #444
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
Codecov Report
@@ Coverage Diff @@
## master #444 +/- ##
==========================================
+ Coverage 84.94% 84.98% +0.03%
==========================================
Files 40 41 +1
Lines 6342 6392 +50
==========================================
+ Hits 5387 5432 +45
- Misses 955 960 +5 |
Could you elaborate on this please?
So static polymorphism, where the "policy" of what to do for the various callbacks is provided by a single object that has a set of functions that conform to the parameters that the current handlers take? Something like this?
I'm not opposed to that, since it's still better than std::function, but I can't think of a way to support the current mqtt_cpp API using static polymorphism. The virtual function way of doing things can do both static functions, and also std::function, and as long as you teach GCC that the overrides for the virtual functions should be always_inline, you end up with the same performance. With static polymorphism, the handlers would need to be injected into the policy object, not the endpoint itself. |
As a metaphor, that would be a bit like calling a standard algorithm with a lambda, where the lambda type is used for instantiating the template code. But I just discovered that an internal queue was used to keep the handlers, which requires in the end type erasure.
Yes indeed
A static polymorphism does not prevent to inject a dynamic one. At least with the static one, the devirtualization is not needed. With that approach, you leave the possible performance penalty to the caller.
I don't see the drawback. |
Just question. Class template I think the the virtual destructor isn't needed because I mean as follows:
Thanks to *1, we don't need virtual destructor. |
Right, the internal queue is necessary to support (among other things) arbitrary numbers of aync_publish() calls in a row, before returning control to boost::asio for processing of async operations.
The drawback is API breakage. That's all I meant. |
Actually, I forgot to think about it. I prefer "protected, non virtual, = default" destructor for abstract base types. This ensures that only code that knows the exact type can delete. I updated the code to make |
Do you mean that I don't need to enqueue my "messages" at the application level and the mqtt client takes in charge to keep all publications in the right order? If yes, what is the strategy in case of failure? Communication interruption? Publication refused by the broker? |
So long as you're calling If there is an unrecoverable local failure, If there is a failure on the brokers end, then you'll either get disconnected, or you'll receive a puback packet with the error. You can save the |
Do note that I would like to support a higher level API than what even See: #374 The TL;DR; is that I want to be able to say: pClient->async_publish(msgdatahere, { /* When sent over network / }, { / when reply received */ }); That will involve an internal It should be very simple to add that to |
…her code, instead of multiple std::functions An optional template wrapper, callable_overlay, is provided that provides a collection of std::functions that can be set to register dynamically changable callbacks for each of the virtual member function calls that can happen.
What about publications still in the queue? Will they be resent after the connection succeeds? Are they purged? |
Let me explain current implementation. It is not only master but also #444 (this PR).
*1 Session Enable means
|
I made some tests with the library, by publishing a sequence of thousand messages with qos::at_least_once (1). |
@ropieur, could you elaborate your question? Please write a detail sequence as follows
If you sequence as above, step 10 is expected behavior. BTW, Here is resend test. https://github.com/redboltz/mqtt_cpp/blob/master/test/resend.cpp |
Here follows my test code. Not sure I wrote something wrong in there.
|
I integrated #444 to my broker and I have done several performance tests on our environment. It works nicely. I merge the PR. Thank you for waiting. |
@ropieur , could you create a new issue for |
An optional template wrapper, callable_overlay, is provided that provides a collection of std::functions that can
be set to register dynamically changable callbacks for each of the virtual member function calls that can happen.