I'm going to vote that we REJECT async-mqtt5 from Boost. My primary reasoning is that so far almost all the review discussion I've seen is focusing solely on the Asio aspect which makes this a miss. I like Asio, and I've used it to deliver products as well. But I don't think this is the MQTT library for Boost. I think libraries like these are a mistake because they're so heavily focused on the ceremony of Asio that the actual meat and potatoes of the library is lost, which in this case is supposed to be MQTT parsing and serialization and broker management. I think there's a lot of utility in MQTT, but what I'd like to see in the future for libraries like these is a first-class interface _without_ I/O. For example, I'm not sure I saw any fuzzing of the underlying parsing code. A non-I/O based interface makes this trivial. I also have a lot of concerns here because the library uses Asio in its interfaces and it also internally uses Spirit. I haven't tried to compile anything but I can only imagine the binary size and the compilation times for a realistic project using this code. I don't have a lot of experience with MQTT as a protocol but my operating assumption is that if TLS/SSL can be made without I/O, so can anything else. I think exploring this design space will lead to a much better outcome for a library going into Boost. You can see prior art here via rustls, OpenSSL's BIO pairs, and Botan which uses a synchronous callback-based interface for handling things. By focusing on creating a pure protocol library, you give users the ability to add MQTT to their own I/O layers which has the extensibility and genericity I'd expect from a Boost library. It will also likely enable the library to be compiled which in this case would be a huge boon. For example, I have an asynchronous runtime which is dramatically faster than Asio and I'm capable of handling low-level networking coding but I can't use this library with my own. Instead, I'd have to roll my own MQTT support. In the ideal case, I'd be able to treat this library like I would Botan and I'd add MQTT support non-intrusively. All this being said, a protocol library that comes with an Asio-based impl is perfectly fine. My only qualm is when the library _only_ supports Asio as seems to be the case here. - Christian
Hi Christian, thanks for your review!
On 22.10.2024., at 18:51, Christian Mazakas via Boost
wrote: I'm going to vote that we REJECT async-mqtt5 from Boost.
My primary reasoning is that so far almost all the review discussion I've seen is focusing solely on the Asio aspect which makes this a miss.
I like Asio, and I've used it to deliver products as well. But I don't think this is the MQTT library for Boost.
I think libraries like these are a mistake because they're so heavily focused on the ceremony of Asio that the actual meat and potatoes of the library is lost, which in this case is supposed to be MQTT parsing and serialization and broker management.
I think there's a lot of utility in MQTT, but what I'd like to see in the future for libraries like these is a first-class interface _without_ I/O. For example, I'm not sure I saw any fuzzing of the underlying parsing code. A non-I/O based interface makes this trivial.
I also have a lot of concerns here because the library uses Asio in its interfaces and it also internally uses Spirit. I haven't tried to compile anything but I can only imagine the binary size and the compilation times for a realistic project using this code.
I don't have a lot of experience with MQTT as a protocol but my operating assumption is that if TLS/SSL can be made without I/O, so can anything else. I think exploring this design space will lead to a much better outcome for a library going into Boost. You can see prior art here via rustls, OpenSSL's BIO pairs, and Botan which uses a synchronous callback-based interface for handling things.
By focusing on creating a pure protocol library, you give users the ability to add MQTT to their own I/O layers which has the extensibility and genericity I'd expect from a Boost library. It will also likely enable the library to be compiled which in this case would be a huge boon.
For example, I have an asynchronous runtime which is dramatically faster than Asio and I'm capable of handling low-level networking coding but I can't use this library with my own. Instead, I'd have to roll my own MQTT support. In the ideal case, I'd be able to treat this library like I would Botan and I'd add MQTT support non-intrusively.
All this being said, a protocol library that comes with an Asio-based impl is perfectly fine. My only qualm is when the library _only_ supports Asio as seems to be the case here.
- Christian
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Ivica Siladic
2 octobre 2024 à 18:51 "Christian Mazakas via Boost"
I think there's a lot of utility in MQTT, but what I'd like to see in the future for libraries like these is a first-class interface _without_ I/O. For example, I'm not sure I saw any fuzzing of the underlying parsing code. A non-I/O based interface makes this trivial.
By focusing on creating a pure protocol library, you give users the ability to add MQTT to their own I/O layers which has the extensibility and genericity I'd expect from a Boost library. It will also likely enable the library to be compiled which in this case would be a huge boon.
For example, I have an asynchronous runtime which is dramatically faster than Asio and I'm capable of handling low-level networking coding but I can't use this library with my own. Instead, I'd have to roll my own MQTT support. In the ideal case, I'd be able to treat this library like I would Botan and I'd add MQTT support non-intrusively.
I'm surprised that this remark did not raise more reaction. I'd like to put a very big +1 on what Christian said. For what it's worth, the platforms i'm currently mostly working with are Xenomai/Linux and FreeRTOS. Asio is unusable on both. I don't think it can be used on Zephyr OS as well. AFAIK it can't be used in any real time / embedded os (well, maybe RTLinux or Qnx). MQTT is advertised as an IOT protocol. I know so-called things are growing more and more to be standard linux devices, but there are still plenty of them which are not. My understanding is that the proposed library is not usable in such platforms, due to the lack of asio. Is that correct? If it is, the next question is what would be the amount of effort that would be needed to put the parsing / interpretation layers outside the networking layer, and if there are there any plans to do it? Christian mentionned fuzzing as an immediate benefit. My experience tells the same, pure protocol libraries are a lot easier to unit test than io libraries.
All this being said, a protocol library that comes with an Asio-based impl is perfectly fine. My only qualm is when the library _only_ supports Asio as seems to be the case here.
I would even add that supporting asio is a very good case of testing the validity of the design of an underlying protocol library. A pure protocol library which has not been tested against asio may well miss its target. Regards, Julien
On Fri, Oct 25, 2024 at 2:43 PM Julien Blanc via Boost
2 octobre 2024 à 18:51 "Christian Mazakas via Boost"
a écrit: I think there's a lot of utility in MQTT, but what I'd like to see in the future for libraries like these is a first-class interface _without_ I/O.
I'm surprised that this remark did not raise more reaction. I'd like to put a very big +1 on what Christian said.
FWIW, that's also what went through my mind reading Christian. And I was surprised when Vinnie didn't jump on this, since he's adverstised his own libraries going in that direction as well. And even though I have no skin in this game, since I'm only on ASIO-supported OSes, and not in the MQTT target market, I think Christian makes a very good point. Designing for testability is always something I strive for, in my own libs. --DD
On Fri, Oct 25, 2024 at 6:04 AM Dominique Devienne via Boost < boost@lists.boost.org> wrote:
...I was surprised when Vinnie didn't jump on this,
I think Boost is better off with async-mqtt5 than without it. In theory, splitting a library up into a protocol library and an I/O library is better engineering. However in the case of the MQTT protocol the heavy lifting is by far in the I/O code with its retries and strategies for implementing the QoS. And a review should evaluate the library we have, not the library that we think it should be. Thanks
On Fri, Oct 25, 2024 at 4:04 PM Vinnie Falco
On Fri, Oct 25, 2024 at 6:04 AM Dominique Devienne via Boost
wrote: ...I was surprised when Vinnie didn't jump on this,
the heavy lifting is by far in the I/O code with its retries and strategies for implementing the QoS
One could argue the QoS part is also I/O independent, albeit sitting "on top" of the I/O, unlike the protocol handling. And the ability to mock the IO, would allow testing and fuzzing the QoS in a way that would be more difficult when it mixes with the I/O, unless when using sophisticated simulation frameworks for I/O, requiring possibly specialized kernels or hardware.
On Fri, Oct 25, 2024 at 7:38 AM Dominique Devienne
...the ability to mock the IO...
I/O can be "mocked" just fine with Asio based libraries (see Beast). Although async-mqtt5 might need a bit of refactoring around the reconnection logic to make it more abstract. See: https://github.com/boostorg/beast/blob/0078272001903f9f2dec91362d8afd89a7a71... Thanks
Dominique Devienne wrote:
On Fri, Oct 25, 2024 at 2:43 PM Julien Blanc via Boost
wrote: 2 octobre 2024 à 18:51 "Christian Mazakas via Boost"
a écrit: I think there's a lot of utility in MQTT, but what I'd like to see in the future for libraries like these is a first-class interface _without_ I/O.
I'm surprised that this remark did not raise more reaction. I'd like to put a very big +1 on what Christian said.
FWIW, that's also what went through my mind reading Christian. And I was surprised when Vinnie didn't jump on this, since he's adverstised his own libraries going in that direction as well.
And even though I have no skin in this game, since I'm only on ASIO-supported OSes, and not in the MQTT target market, I think Christian makes a very good point.
Designing for testability is always something I strive for, in my own libs. --DD
It is, however, significantly harder to design sans-io libraries than it is ones where the I/O layer is fixed and known. If we reject all libraries of the second persuasion, we may not get any of the first one, and we'll be left with nothing.
I forgot to disclose in my original post that I am a staff engineer with the C++ Alliance, so I am doing so now. Back to the review... If TLS, the most important protocol in networking, can be made sans I/O, so can all the others. The thing with Redis and MQTT is that there's no shortage of quality production-ready libraries in the wild. In my mind, there's no strong onus to actually get a lib like Redis or async-mqtt5 into Boost because, well, you can just use any number of competitor libs and ship your product. I think for Boost, we should strive for something actually cutting-edge, something that lives up to the reputation. For IoT devices, you're not going to be able to use Asio. I was chatting with another engineer who was talking about how his MQTT code is used in thousands of devices in people's homes. Except he does all this on top of libuv, meaning Boost is a non-starter in this regard. I think in many ways, having a clean sans-I/O layer will probably actually make the I/O parts cleaner. It works really well for TLS and HTTP. I don't see why MQTT is different. - Christian
Christian Mazakas wrote:
I think in many ways, having a clean sans-I/O layer will probably actually make the I/O parts cleaner. It works really well for TLS and HTTP. I don't see why MQTT is different.
Assuming that your goal is to get a sans-io MQTT library in Boost, the question reduces to which path will be more likely to produce this outcome: 1. Accepting an I/O MQTT library first 2. Rejecting the I/O MQTT library While (under different circumstances) there exist valid arguments in favor of (2), in this case I think that (1) is a clear winner because the other three cases we can observe have all taken it.
On Fri, Oct 25, 2024 at 8:41 AM Peter Dimov via Boost
Assuming that your goal is to get a sans-io MQTT library in Boost, the question reduces to which path will be more likely to produce this outcome:
This really only happens when the author agrees it's worth doing and then they actually do it. Even then, Marcelo has claimed only partial support. HTTP/2 is a similarly multiplexed protocol. I'll agree that handling multiplexing with a protocol library is non-trivial, but I think Botan's shown that a callback-based approach for handling these kinds of things can create a satisfactory API. Users feed in whatever data they have and if a complete message for a stream comes in, you just invoke the user's callback. I'm hesitant to change my vote to a conditional accept because I feel like it implies some sort of a deadline/timeline. I think if we know the ultimate form the library should take, it's better to be patient and wait for that version than to accept-and-pray. The sans-I/O form is worth another review, in my opinion, because adding this makes it a new library, essentially. Plus, I'll actually try and use it with my project Fiona, which stands for Fastest I/O in North America. - Christian
This really only happens when the author agrees it's worth doing and then
On Fri, 25 Oct 2024 at 20:14, Christian Mazakas via Boost < boost@lists.boost.org> wrote: they actually do it. Even then, Marcelo has claimed only partial support. That is not how my previous message should be understood. The Redis protocol implementation in Boost.Redis is 100% sans-io. Multiplexing is not part of that specification [2], which that does not mean it can't be done. [1] https://github.com/redis/redis-specifications/blob/1252427cdbc497f66a7f8550c... [2] https://github.com/redis/redis/issues/12873 Marcelo
On Fri, Oct 25, 2024 at 12:27 PM Marcelo Zimbres Silva
That is not how my previous message should be understood. The Redis protocol implementation in Boost.Redis is 100% sans-io. Multiplexing is not part of that specification [2], which that does not mean it can't be done.
Huh, fair enough I suppose. I'm kind of confused about how you've described things but I'll take your word on it. Interestingly, I just went to examine the docs for both libraries (MySQL and Redis) and neither one seems to have actually documented what the sans-I/O interface looks like. I don't think this model is as successful as we're claiming it is. I think a more direct "Hey, you can use this library without I/O, here's how" style of documentation would help here and it should be a pointed focus of the library. Neither MySQL nor Redis seem to do this. I'll trust the claim that both libraries can work without I/O, I just don't know how to do it. - Christian
On Fri, 25 Oct 2024, 22:06 Christian Mazakas via Boost, < boost@lists.boost.org> wrote:
On Fri, Oct 25, 2024 at 12:27 PM Marcelo Zimbres Silva
wrote:
That is not how my previous message should be understood. The Redis protocol implementation in Boost.Redis is 100% sans-io. Multiplexing is not part of that specification [2], which that does not mean it can't be done.
Huh, fair enough I suppose. I'm kind of confused about how you've described things but I'll take your word on it.
Interestingly, I just went to examine the docs for both libraries (MySQL and Redis) and neither one seems to have actually documented what the sans-I/O interface looks like.
MySQL is implemented as a sans-io layer that is private. I haven't had any users request it, so I never made it public. It's a significant increase in the public API, so I'm reluctant. I'm already benefitting from the easier testing and fuzzing. If you (or anyone reading this) do think there is a real use case for it, let me know. Regards, Ruben.
On Fri, 25 Oct 2024 at 14:43, Julien Blanc via Boost
I'm surprised that this remark did not raise more reaction. I'd like to put a very big +1 on what Christian said.
There is a strong precedent in Boost for first solving the IO problem and then factoring out the protocol part. I know Vinnie is writing new http libraries based on his experience with Beast, Boost.MySql has also been refactored into sans-io components (if I understood Ruben correctly at Slack, please correct me if I am wrong). In Boost.Redis you can also create requests and parse RESP3 all without IO and Asio [1], only the multiplexing part is still coupled to IO but even that I might factor out into a sans-io component. If we all used OP criteria there would be no Boost.Beast, Boost.MySql and Boost.Redis since none of them had a clear sans-io protocol component at their submission. Marcelo [1] https://github.com/boostorg/redis/blob/b8a52e5e61275bc7dbfa6379cd9adf1053525...
participants (8)
-
Christian Mazakas
-
Dominique Devienne
-
Ivica Siladic
-
Julien Blanc
-
Marcelo Zimbres Silva
-
Peter Dimov
-
Ruben Perez
-
Vinnie Falco