Live data from Hacker News

Crow – C++ Microframework for Web, inspired by Python Flask

github.com

41–50 of 65 posts

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#41
post #19

C++ _micro_framework using boost. Just couldn't resist to notice that. ;) (I know that boost consists of many libraries, many of them are header only, etc. so using them doesn't necessarily result in terrible bloat.) Will have a proper look at it later.

I noticed that to. For C++03 you might need it for scoped_ptr/shared_ptr, but not if you're going to require C++11. If you're going down the -lpthread route you should probably just use them rather than forcing the include on boost threads.

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#42
I don't code much in C++ but recently I started a project just for fun and found it much easier to make a FastCGI app than I anticipated. Yes, there are still some exceedingly low-level stuff to write by yourself, but overall, it's just fine.

For example, this is how I handle routing: http://goo.gl/G3jvGp

A simple static map of regexes and pointers to methods will do the task nicely, and the principle is extendible if I need to create or compose complex apps.

There are still things which I would need to encapsulate to make it a rapid development framework (such as QUERY_STRING handling in http://goo.gl/l7Ff75) but it's surprisingly non-painful.

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#43

The way your routes work mean that a response is expected to be immediately generated and returned. It would be much nicer if a response object was passed to the callback and you could return immediately from the callback, but send a response independently, when you are ready. Kind of like this: CROW_ROUTE(app, "/about") ([](Response res){ res.send("About Crow example"); }); Why you might ask? So you can do this: CRO…

If all of this is happening in it's own thread (and there's probably 1 thread per connection), why add the overhead and complexity of something like this?

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#44
post #43

The way your routes work mean that a response is expected to be immediately generated and returned. It would be much nicer if a response object was passed to the callback and you could return immediately from the callback, but send a response independently, when you are ready. Kind of like this: CROW_ROUTE(app, "/about") ([](Response res){ res.send("About Crow example"); }); Why you might ask? So you can do this: CRO…

If all of this is happening in it's own thread (and there's probably 1 thread per connection), why add the overhead and complexity of something like this?

I've looked at his code and that is not how it works. It uses boost::asio. You specify how many io_service threads to run. It is not 1 thread per connection. You could easily have 10000 connections spread across 4 threads for example. The threads that handle the connections are the same threads which run the callbacks. You wouldn't want threads being blocked by callbacks that take a long time to run. You'd want to pass those operations off to a different thread pool. So you would want to be able to do what I have suggested.

Also, you said this adds complexity and overhead. I dispute that it adds complexity. For most people: "return stuff" vs "res.send(stuff)". And I wouldn't assume that it would add any overhead either. If you disagree, let me know when you've read the code and understand how boost::asio works.

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#45
post #16

Earlier quoted context omitted.

Header-only libraries have several advantages (see http://en.wikipedia.org/wiki/Header-only ). Most-notably, they are dead-simple to include with a project, as opposed to having to separately build and link to a shared-library.

Yeah but usually "header-only" implies templates, of which there seems to be little in this case. Without templates there's little point in putting everything in headers because all the code becomes inline. Inlining everything is bad because: - it makes the binary much bigger. - the smallest code change forces library users (applications) to be recompiled. For libraries it's usually better to go to the other extreme:…

It may seem unusual because you haven't seen it, but header-only libraries are perfectly valid for small, focused libraries.

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#46
post #35

Earlier quoted context omitted.

`static` will result in a copy of f for every translation unit (without LTO, at least). `inline` will not. `static inline` is effectively the same as `static`, with a slight hint to the compiler to inline the call. `inline` is used extensively in C++ to make header-only libraries possible; otherwise you'd get constant symbol clashes during linking. With `static` you would get enormous size blowup. It has little to do…

Thanks for that. I always hoped that static C functions would not be generated if they are never called, at least. Which I can't see anything to prevent. It sounds like you've confirmed my intuition about inline in C, and I find inline to be only marginally-useful at best. inline functions are syntactically-prettier than macros, but they lose the other major benefit of macros, which is increased flexibility about typ…

`inline` indicates to the compiler: "this function has external linkage, and no matter how many times it's defined it is to be defined only once in the final linked output". It's the same as if there was no inline, but when the linker finds multiple definitions of the same function it is allowed to ignore them instead of failing. It also serves as a inlining hint to the compiler in its free time.

Note that you don't necessarily have to type `inline` to have inline functions. Methods defined in the declaration of a class are implicitly inline; so are template functions (but not explicit specializations).

The reason it's called `inline` instead of something else probably has something to do with the committee's aversion to new keywords, and commitment to backwards compatibility. Changing `static` would probably break a lot of code: think what would happen to static variables inside static functions.

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#47

The way your routes work mean that a response is expected to be immediately generated and returned. It would be much nicer if a response object was passed to the callback and you could return immediately from the callback, but send a response independently, when you are ready. Kind of like this: CROW_ROUTE(app, "/about") ([](Response res){ res.send("About Crow example"); }); Why you might ask? So you can do this: CRO…

I agree that allowing implementing long polling with crow is important, just I didn't know a good way to do that. Your suggestion is big help.

I think supporting both way is better if there is a enough explanation. I don't want to drop a simpler way to do the same job.

  CROW_ROUTE(app, "/about")
    ([](){
        return "About Crow example";
    });

  CROW_ROUTE(app, "/about")
    ([](Response res){
        res.send("About Crow example");
    });

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#48

Earlier quoted context omitted.

Yeah but usually "header-only" implies templates, of which there seems to be little in this case. Without templates there's little point in putting everything in headers because all the code becomes inline. Inlining everything is bad because: - it makes the binary much bigger. - the smallest code change forces library users (applications) to be recompiled. For libraries it's usually better to go to the other extreme:…

It may seem unusual because you haven't seen it, but header-only libraries are perfectly valid for small, focused libraries.

How do you justify mass recompilations for every minor version bump or bugfix to your users?

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#49
post #46

Earlier quoted context omitted.

Thanks for that. I always hoped that static C functions would not be generated if they are never called, at least. Which I can't see anything to prevent. It sounds like you've confirmed my intuition about inline in C, and I find inline to be only marginally-useful at best. inline functions are syntactically-prettier than macros, but they lose the other major benefit of macros, which is increased flexibility about typ…

`inline` indicates to the compiler: "this function has external linkage, and no matter how many times it's defined it is to be defined only once in the final linked output". It's the same as if there was no inline, but when the linker finds multiple definitions of the same function it is allowed to ignore them instead of failing. It also serves as a inlining hint to the compiler in its free time. Note that you don't…

'static' is old. It must have meant something to Kernighan and Ritchie.

I see no connection to the word inline in the C++ meaning. In C, at least, inline means inline.

My guess is that the C++ inline got its meaning from the winding path of c++ history, and only makes sense in the context of that history.

Re: Crow – C++ Microframework for Web, inspired by Python Flask

#50

Earlier quoted context omitted.

It may seem unusual because you haven't seen it, but header-only libraries are perfectly valid for small, focused libraries.

How do you justify mass recompilations for every minor version bump or bugfix to your users?

This is only a problem if the user structured their code horribly. The library handles HTTP requests, it should be on the edge of the architecture.

Side note: C++ is fantastic in this regard because it makes you suffer every time for excessive coupling. The compile/link times act as a recognizable metric that devs have an interest in minimizing, and the process of doing so produces better code. I love that it is ruthless in punishing poor design.

Post reply on HN