Boost logo

Boost :

Subject: Re: [boost] [http] Formal review of Boost.Http
From: Vinícius dos Santos Oliveira (vini.ipsmaker_at_[hidden])
Date: 2015-08-13 19:20:02


2015-08-13 19:17 GMT-03:00 Rodrigo Madera <rodrigo.madera_at_[hidden]>:

> 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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk