2016-03-15 8:04 GMT-03:00 Artyom Beilis
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.cp... 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/