2015-08-13 19:17 GMT-03:00 Rodrigo Madera
If you can abstract it for HTTP, I can assume it can be done for others as well. Just take your abstractions and implement them for other protocols. That would still make Boost.Asio.Extensions interesting.
[...]
Message abstraction with various representations (binary, textual) is a common pattern in networking code. I would expect any other protocol implementations to use it, and if possible, use different backends.
Fair enough. Then, considering we're heading this path, what are the other implications? How many maintainers can we have per Boost library? It seems a hard job to allow only one maintainer to maintain the implementation of all protocols. What if ftp also have a socket? Will we type boost::asio::ftp::socket? Why not just boost::ftp::socket? Other points that are I'm missing? cpp-netlib, pion and many other provide request routers and server
abstractions. They usually couple all abstractions together and use a design like:
- There is the server+request-router+handler+thread-pool+... - Request factory, which the user will extend and pass to the above inflated abstraction.
But this is good for a high-level API.
Until the flaws start to show. We still see hate against iostream idea of mixing input/output and string format to this date. About the fine high-level abstraction: Can I use it in multi-threaded design? How are the threads going to be used? Will connections be shared among them or will be fine-grained requests shared? Which scheduling algorithm will be used? Can I provide my own thread-pool? What about other kinds of object pools (e.g. message pools)? Can I provide a custom allocator? Can I stop this server at anytime? What are the guarantees? These are just some initial questions. But the most problematic flaw in the design is the lack of consideration to alternative HTTP backends. If the library is accepted, I'm thinking to deliver features soon into a experimental namespace for which I give no guarantees related to API stability and slowly move them to stable API as I gather feedback and do more research. As I stated, it would be nice to have both APIs. Have a lower level API and
then an abstraction.
Yes, but the main players will be the same you already see here. You'd use a message object and a communication channel to respond to requests. Since you use Asio, you won't need all those details of cpp-netlib, but the
rest could be compile time policies into a higher API.
That looks like a good start.
The thing here is that I'm very ambitious about this project and I estimate
I'd take as long as the already spent time just to deliver the request router. I want to be sure that I'm providing the best request router possible to write. Something that could go into the C++ standard and nobody would fear to be deprecated in the future.
Good! You should be. But we need it now to use Http in a real world application, or you will be leaving to users the responsibility of implementing Http code that should be inside the library already.
Even if not the perfect solution at first.
Actually, if it's not a perfect solution at first, I'll end up either deprecating API or breaking API. I don't like either approach, so the remaining option is to deliver incrementally (not complete at first).
A big challenge to the request router is that it can become rather
inefficient if I put customization points everywhere. And if I think about performance, I remember that most of the request routers I saw allow you to change the rules at runtime when this feature is rarely needed. Maybe some TMP magic can help here.
Could you please elaborate why?
As I see it, if you put the customized interceptors in place, only (and only) that request/response would "suffer".
I agree that runtime rules are seldomly needed. In my experience, at least.
Well, your application routing rules might not need to touch the HTTP headers at all, just the request path/resource/uri. Then the code to match based on headers (this include authentication, session...) is just eating memory and CPU. This problem can be solved with TMP if the rules are static. As an hypothetical example, you might consider a rule like check_header("authorization" "Digest username=\"Mufasa\"..."). You have the request router object: router r; and you have routing rules: rule_t r1(/* ... */); handler h1(/* .... */); r.add(r1, h1); If we were to allow check_header rule, rule_t would need to store it somehow. But if you don't use this rule, memory and CPU is just being wasted. - Benchmarks
I'd suggest to focus on correctness. It's very tricky to get a correct implementation that will portably work among several little know implementations.
What if the design is very far from others at the time?
What if the basic Asio examples (with some processing that actually suffices some use cases) outperform severly?
Since you have several competitors, benchmarks, to me, are important.
Even if you design a perfect API with every abstraction possible, I wouldn't use it if it cut my TV streaming server performance even by a small percentage. It wouldn't be an advantage.
I want to be sure that the abstraction won't cost me more than I'm willing to pay.
And theoretically, there is no reason why Boost.Http it should underperform if enough static customization is allowed.
Fair enough. Now I'm convinced to compare against Asio HTTP examples, even if these two solutions aren't feature-comparable. You just should not use an unmaintained copy & paste
solution.
Sorry, I didn't understand. Do you mean to copy and paste benchmark code?
No, I meant the Asio HTTP examples adopted as a solution. Sorry for not being clearer in the earlier email. We have been talking sporadically about your project since it was approved
in GSoC, remember?
I raised you my concerns on private messaging as well, way before the review started.
Yes, it took a long time to polish the core. When you aim to allow alternative backends, you end up reading/researching a lot of specifications to make sure every use case will be possible. And this translate into small details on the specification (the concepts part of the documentation) that not many people would imagine it'd take a long time to get it done. While I agree with some points of Niall, I base my opinions on my own use
cases. I download the tree, I compile it (when needed), read the examples, do the tests, and then raise my view. I'm not even done playing with Boost.Http.
I see if I would have done it better. I see if it would make my work simpler. I see the reasoning.
And I'm very thankful about people like you that are dedicating a lot of time to give such meaningful feedback. I hope to deliver an awesome library to pay you guys back. Please don't use this "Niall started it" as a shield to unacknowledge the
problems pointed out. You didn't even respond to my initial points, disregarding them as someone else's. But if you read carefully, you will see that those are basic and important issues that affect the Boost quality I'm used to.
The points that I didn't commented were points that I didn't disagree. You were simple right in my view, so there is no need to answer anything. I'll re-read the whole thread after the review to gather points where the library can be improved and implement them. The only question I didn't answered yet was Darren Cook's about HTTP 2, for which I'm writing a prototype. - Conclusion
If you only wanted to review design, then a full library inclusion review wasn't needed. I just don't see it done *yet*.
Actually, I complain a lot about the design because that's where the breaking changes are, but I was obsessive with the implementation too. It's fair to state that I wasn't so obsessive with tooling, tough, as Niall noticed. However, tooling is improving (CI on several systems with some sanitizers are already being used). Even a conditional acceptance would be nice because then I'd have proved the proposed API is right and then I'd just need to improve completeness or implementation or any other point raised. And the small core proposed is intentional. You guys are already complained about little time to review such complex project. And I'm having a hard time defending this small core already. Imagine if I had proposed the polemic parts that I'm planning to implement. -- VinÃcius dos Santos Oliveira https://about.me/vinipsmaker