6 ms·
Show HN: Oat++ – Zero-dependency C++ framework for high-performance web services
- deleted 8y ago[deleted]
- clishem 8y agoI wonder how this stacks against Cutelyst in terms of performance.
- lganzzzo 8y agoHello and thank you for the question! The short answer: - I don't know. - Let Techempower to settle this. I decided to take on Go(net/http) in the initial benchmarks as it shows good performance and even overperformed c++ solutions that claimed to be more performant (in their tests). But! There multiple things that can be tuned especially with c++ servers. And there are multiple tests which show different aspects of server's performance. The problem is that currently I have no resources to do all these tests and what is more important - I think such tests should be made by an independent third party. So I think oat++ should be submitted to Techempower to answer all those questions.
- clishem 8y agoYou are expected to deliver tests to Techempower yourself. Optimizing for those tests is part of the game. ;) net/http is known for being quite slow
- lganzzzo 8y agoYeah, I already looked through requirements. It will take me some time to prepare all that stuff. But I think it's gonna be fun
- lganzzzo 8y agoThe idea of the project is to give user something light, something that could cover a set of basic needs when you develop a web-service (Like rest-framework, basic DI-framework, web-client, connection management, object-mapping etc...) and make it highly customizable at the same time. So when you need to kickoff something from scratch you don't need to do anything more than a git clone starter-project and start coding. And when it comes time for additional requirements you cant easily substitute ex. any SSL backend, any http-client, add http compression etc... And oat++ provides interfaces to configure there things. See more: Example how to create web-service with swagger-uI and auto-documented endpoints https://medium.com/oatpp/c-oatpp-web-service-with-swagger-ui-and-auto-documented-endpoints-1d4bb7b82c21 https://medium.com/oatpp/c-oatpp-web-service-with-swagger-ui...
- Chabs 8y agoWhat is the rationale behind going for from-full-scratch instead of packaging a copy of ASIO with the library? Beating properly-used ASIO performance is going to be a massive uphill battle, especially in multithreaded scenarios. On that note, benchmarks against a simple ASIO http server are a must if performance is your #1 stated goal.
- michaelvoz 8y ago+1 to this. If you are faster than ASIO - consider contributing back. If you are slower, and performance is the goal, what's the point of using your framework?
- _pmf_ 8y ago> What is the rationale behind going for from-full-scratch instead of packaging a copy of ASIO with the library? Is there a way of building ASIO without Boost?
- beojan 8y agoYes, there's a standalone version of ASIO.
- lganzzzo 8y agoI agree. I should schedule to add ASIO vs oatpp benchmark. However performance is not the only thing oatpp has. Among with other features oatpp provides ObjectMapping layer. ObjectMapping layer enables you to do cool stuff like: - autodocument endpoints see https://medium.com/oatpp/c-oatpp-web-service-with-swagger-ui-and-auto-documented-endpoints-1d4bb7b82c21 https://medium.com/oatpp/c-oatpp-web-service-with-swagger-ui... - easily implement custom protocols (I will write article about this later)
- Chabs 8y agoI think you are misunderstanding my question. I am not suggesting that ASIO fills the role your library does. All it is, really, is just fancied-up cross-patform select(). What I'm wondering is: Is there's a specific reason you chose to reinvent that specific wheel?
- IloveHN84 8y agoWhat about TLS 1.3?
- lganzzzo 8y agoThank you for the question, Oat++ provides interfaces to substitute SSL backend. One can easily substitute any SSL backend by implementing two class: - Connection - ConnectionProvider Currently there is an adapter for LibreSSL https://github.com/oatpp/oatpp-libressl/tree/master/server https://github.com/oatpp/oatpp-libressl/tree/master/server But if you need TLS 1.3 one may add GnuTLS adapter for example
- ddorian43 8y agoHave you tried using (or building on top of) seastar-framework ?
- lganzzzo 8y agoThank you for the question, No, I have not tried seastar. But thank you for the tip, I think there might be things for me to point out.
- sytelus 8y agoIs this cross platform? It looks like there is direct dependency on Linux socket APIs.
- lganzzzo 8y agoHello, Thank you for the question! oatpp has been recently tested on: - Linux (Ubuntu 16, 18. CentOS 7.5) - MacOS Windows support is not currently available. But I would love to add it. If there someone with windows machine and willing to help, I will provide all needed assistance. Windows support issue: https://github.com/oatpp/oatpp/issues/2 https://github.com/oatpp/oatpp/issues/2
- FooBarWidget 8y agoHi there, great work writing oat++. I am the author of Passenger (https://www.phusionpassenger.com https://www.phusionpassenger.com), an application server that powers 650.000 companies and sites world-wide such as Apple, Pixar, Juniper, etc. Passenger is mostly written in C++ and like you, performance is a priority for us. I've done a fast code review, and I thought I'd share some of my findings with you. These are based on my experience with writing high-performance servers. You can read about some of my experience in these blog posts: https://www.rubyraptor.org/how-we-made-raptor-up-to-4x-faster-than-unicorn-and-up-to-2x-faster-than-puma-torquebox/ https://www.rubyraptor.org/how-we-made-raptor-up-to-4x-faste... Hopefully you can use my feedback to make oat++ even faster and better. Code review here: https://github.com/oatpp/oatpp/issues/15 https://github.com/oatpp/oatpp/issues/15 I've covered: - Pools and contention - Shared_ptr and atomics everywhere - List vs vector - Zero-copy architecture - SpinLock everywhere - New does not return nullptr? - More documentation - More tests
- lganzzzo 8y agoThanks, this is a really good code-review! I appreciate this!
- M_Bakhtiari 8y agoGood point on the shared_pointers. What's your opinion on using Ravenbrook MPS pools and not deal with refcounts at all?
- lganzzzo 8y agoMemory management, and pools. Memory management is definitely super important and has big impact on the performance. Also there is a memory fragmentation issue that you should keep in mind building server apps. Solving this problems is time consuming and you need to do a lot of experiments in order to tune all this system. So if there is a robust time-proved solution for solving this problems it is definitely worth of considering. shared_ptr and refcounts - actually it is a compromise (like any other solution). On the one hand you could avoid refcounts, atomics etc. On the other hand you have a framework for the end user. And user may be not so familiar in depth of your framework's thread management and concurrent access to some shared objects. Also end-user may decide to bring in some other library which for example uses shared_ptr. And what user should do if he has to share some object among std::shared_ptr and your own custom shared-ptr:)? This is the reason I decided to go with std::shared_ptr (with it's atomic refcounter) as I mentioned in the code-review in the response https://github.com/oatpp/oatpp/issues/15 https://github.com/oatpp/oatpp/issues/15 Now about Ravenbrook MPS pools in particular: It seems to be a robust time-proved solution which may help you to avoid a lot of pain. As for oatpp - oatpp claims to be zero-dependency at the moment. So no external dependencies are considered at the moment. This may be changed at some moment in the future but not for now.
- lganzzzo 8y agoDid you notice that https://oatpp.io https://oatpp.io is served by oatpp :)?
- tfigment 8y agoPerhaps my NVidia tablet is out of date but that link comes up secure connection failed under Firefox Focus. I have not done deep dive to study but not a common issue for me with focus. (Edit: might be intermediate cerificates issue.)
- saagarjha 8y agoJust a small thing I found: your site seems to break scrolling on iOS.
- lganzzzo 8y agoYeah known issue, I am not a JS master:(
- delta1 8y agoOn a corporate proxied network I'm getting this response server=oatpp/0.18.9 code=431 description=Request Header Fields Too Large message= Can't parse headers It seems to work okay on the non-corporate network
- lganzzzo 8y agoThere is a limitation on the header size in the oatpp html parser. Think I should tweak this. Thank you for the note!
- billconan 8y agoI have a question. I want to adopt oatpp.io, but I'm using a synchronous database driver mongo-cxx-driver. Can I still benefit from oat++'s coroutine? Also, when using coroutine, will the server be a single-thread process? or it will be a multiple thread process with each thread using coroutines (to fully utilize the cpu)? If my server wants to visit third party rest APIs in an asynchronized way, what's the best asynchronized library to choose to make use of coroutine?
- lganzzzo 8y agoHave you noticed oatpp ApiClient (retrofit-like client wrapper)? This is another trick oatpp's ObjectMapper layer can do. The oatpp-consul client is built using oatpp ApiClient. see ApiClient in the oatpp-consul https://github.com/oatpp/oatpp-consul/blob/master/rest/Client.hpp https://github.com/oatpp/oatpp-consul/blob/master/rest/Clien... example how to do client requests https://github.com/oatpp/oatpp-examples/issues/3 https://github.com/oatpp/oatpp-examples/issues/3 It is also possible to build your own RequestExecutor based on ex. Curl
- petters 8y ago> return createResponse(Status::CODE_200, "Hello World!"); Is "Status::CODE_200" a useful abstraction over just "200"?
- lultimouomo 8y agoAn HTTP status has both a numerical code (200) and a textual reason (OK).
- gpderetta 8y agoAssuming that's an enum, the compiler will tell you if you miss one case in a switch statement. Also if you mistype 200 for example as 20 or 2000 the compiler will also tell you. None are huge reasons, but it is nice and cheap.
- lganzzzo 8y agogood point
- Matthias247 8y agoLooks pretty cool and easy to use, at least for the synchronous methods. The async methods could use a little bit more documentation, e.g. what is really async about them (what is Action? Some kind of deferred response? Can you store the request objects there for longer than the act() methods scope? Etc). What I would also like to see there are additional examples which show how streaming the request/response body is done, e.g. for file uploads and downloads or SSE.
- lganzzzo 8y agoHey, thank you for the feedback! It is really very important to me what seems unclear to user, and what info to add.