Boost logo

Boost :

Subject: Re: [boost] [http] Design ideas for a request router
From: Vinícius dos Santos Oliveira (vini.ipsmaker_at_[hidden])
Date: 2016-03-15 12:37:31


2016-03-15 8:04 GMT-03:00 Artyom Beilis <artyom.beilis_at_[hidden]>:

> I suggest start from requirement i.e. what is needed - some samples
> and see how it works. To be honest copying callback isn't something
> that should be done - may be pass a reference/iterator to a next
> callback - but copy?
>
> Also remember that usually stuff that is being executed is rarely
> simple function but has lots of relations so... simple lambda
> isn't enough.
>

Previously you mentioned the "tree style" as the majority of what people
need and the "chained style" as just a hip from NodeJS people.

I intend to implement the "tree style" later (and I think I'll try to
mirror the crow design a lot).

For now, I think you're suggesting I should revisit how I design things and
question every of my decisions again. I don't undestand what you're
suggesting by what the "next" argument should be. I may certainly be
misinterpreting a (large) part of what you're arguing. However, I need to
do some effort and show that I need better clarification so we can
understand each other.

Things got complicated when I tried to think what should be the type of
"next". If I build a static router (like the one I'm currently drafting), I
just take a rule and a handler (whose type can be different each time) and
create a new type out of it. The only reasonable answer I found was using a
std::function<> or creating a custom http::function<> that would serve the
same purpose (which I don't like).

I thought about using an iterator instead next, but because each added
handler will return a different router there isn't a single collection with
multiple items and iterator would also need type erasure. I decided the
type erased object would be statically allocated internally in each layer
of the router (I can revisit this later) and you'd only pay for the
indirection if needed to "reroute"/call-next. A plus point is that you'll
only reserve the size you need (different than std::function which may
store a few extra bytes to avoid heap allocation).

Anyway I was still being puzzled about what signature the handler should
have (doubts mainly provoked by the "next" argument). I'm concerned about
providing some form of http::utils that would have lots of "ready" handlers
(like file server, 404 not found...) and the signature must be consistent.
The signature would require a message already and I thought I could just
embedded the next iterator/function/type-erased-next-searcher into the
message. This decision would allow me to share the same "handler
algorithm/utility-function" within "chained routers" and "tree routers"
because of compatible signatures (tree routers don't have a "next"
argument).

I guess this is confusing not only to me and I'll have to finish the whole
set of routers before the next round of feedback.

Anyway, I have pushed new commits into the router2 branch and I'd like to
know what you guys think about this way of declaring a message_t:
https://github.com/vinipsmaker/asiohttpserver/blob/router2/example/router.cpp#L131-L132

I'll have lots of with_ types (e.g. with_session, with_date) that will move
information from the headers to properly typed fields and do other things
like the router embedded the searcher/next-handler into the message. All
this is just to the user convenience and none will be required (you just
pay for what you use). However I wanted an easy way to declare new message
types and after the feedback of the brazilian C++ user groups I've come up
with this API. What do you guys think about it?

-- 
Vinícius dos Santos Oliveira
https://vinipsmaker.github.io/

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