Cutelyst 2.8.0 released

Cutelyst a Qt/C++ Web framework got a new release!

This release took a while to be out because I wanted to fix some important stuff, but time is short, I’ve been working on polishing my UPnpQt library and on a yet to be released FirebaseQt and FirebaseQtAdmin (that’s been used on a mobile app and REST/WebApp used with Cutelyst), the latter is working quite well although it depends ATM on a Python script to get the Google token, luckly it’s a temporary waste of 25MB of RAM each 45 minutes.

Back to the release, thanks to Alexander Yudaev it has cpack support now and 顏子鳴 also fixed some bugs and added a deflate feature to RenderView, FastCGI and H2.

I’m also very happy we now have more than 500 stars on GitHub 🙂

Have fun https://github.com/cutelyst/cutelyst/releases/tag/v2.8.0

Advertisements
Cutelyst 2.8.0 released

Cutelyst 2.7.0 released, async is back!

Cutelyst a Qt/C++ Web Framework just got a new version. This time bringing back proper async support.

Perl Catalyst Framework was conceived as a sync/blocking framework, due that the Mojolicious framework was created, NodeJS and a few other web frameworks have pushed the async programming to the web. Performance wise being async doesn’t mean you get faster response times, rather the opposite, the need to unroll stack and make extra calls makes a CPU bound application slower.

But depending on the problem to solve it allows you to serve more users at the same time, using the same CPU cores. A typical modern application might receive a request from a Phone App then do a REST API call to an external API which might take 2ms or 200ms for the reply. While waiting for the response, typical sync/blocking applications can’t process more requests, or have to spawn more threads increasing RAM consumption and leveraging concurrency to the OS scheduler. On an Async web application, you can process another request while you wait for the previous request, thus possibly making the first request reply to be sent back to the user at a later time than if there was a dedicated process just waiting for his reply.

So, both ways have pros and cons and IMHO I’d like to support them both. When I started Cutelyst I thought that if I ever need async I could have a local QEventLoop to wait for the reply and would be able to deal with async requests, not recently I found out that supporting QEventLoop was causing stack overflow due it being used in pipelined scenarios, after that I removed it’s usage and performance improved in PlainText tests of TechEmpower, so I advised against using it and marked Cutelyst as not async.

Recently I got the need to call a few APIs from a REST API I did with Cutelyst, QNeworkAccessManager is an async only API, so either I create a thread for it to mimic sync behavior or allow Cutelyst to be used in async mode, of course I did the latter. The Context class has now detachAsync() and attachAsync() methods.

When you c->detachAsync(), you tell the engine to not send the headers and body immediately to the client, this will also break the action chain, meaning an end() method won’t be called, then when you get your async reply you call c->attachAsync().

Once c->attachAsync() is called the action chain is resumed so the end() method that possibly would render the HTML can perform it’s job.

It’s important to always be child ( QObject->setParent(…) ) of the Context pointer as if the client closes the connection it might be deleted.

This release was not only made of async:

  • A helper UserAgent singleton was added so that you have a thread_local QNetworkAccessManager with static methods to do more common REST tasks like sending a QJsonObject (yes, eventually I find time to write a patch for QNAM)
  • A new Sql::Transaction class gives you a scoped SQL transaction, preventing the mistake of not rolling back when you leave the scope in case of an error.
  • A few Headers helpers like ETag and If-Match comparison
  • Sebastian Held added support for dealing with Front-End Proxy Headers
  • Improved Stats precision using QElapsedTimer::nsecsElapsed()

And finally Cutelyst is not “half modern” CMake anymore, if that can even exist. The include directories of the exported Targets are now properly exported, so that you can remove:

include_directories(
    ${Cutelyst2Qt5_INCLUDE_DIR}
)

Have fun https://github.com/cutelyst/cutelyst/archive/v2.7.0.tar.gz

Cutelyst 2.7.0 released, async is back!

Facebook AccountKit with Qt/C++ on Android

Facebook’s AccountKit is an authentication service that can use your email or phone number to login to your services, it doesn’t require that the user has a Facebook account, just a valid email or phone.

The cool thing about it is that it sends SMS for free, and although sending SMSs is cheap being free of charge is something you might want to look when creating a new App, in fact here in Brazil some big Apps do make use of it.

So long story short story I wanted to add this to my Qt Android App.

Thanks to the great help of Kai Uwe Broulik who had give some tips on the past on how to call Java code I started with this same approach:

  • Create a Java file
  • Put the Java code of AccountKit there
  • Call the static function of Java from C++

And… it did work BUT I was unable to get the result, this is because the Java code starts a new Activity and returns the result on a method that must be implemented on the code that Qt creates for starting your activity, so this means I’d need to change the XML manifest to call my subclass instead of what Qt provides, and would need to do a bunch of other stuff myself, basically would get more maintainance work to do.

So another option would be to do all of this from C++, which Kai said it would be better at first, but doing a bunch of JNI scared me a bit, also I hadn’t found the reference page to their API (which he found after the work was done lol). There’s a tool called javap that can dump the Java signature of what is inside the package you got, so with the help of this we went on porting all the calls to AccountKit API to C++/Qt, this way we can call QtAndroid::startActivity() passing a pointer to a class that will handle the result of the new Activity, all in C++ 🙂 .

There were some initial issues with the Enums used (aparently some new Java7 stuff), but the code now doesn’t require a single line of Java code, which is great when integrating in Qt Android Apps.

The result is on GitHub, so if you need this just copy the integration class, it has IFDEFs so if you are testing on !Android it will compile fine. (You still need to follow the Gradle and manifest integration that’s on their dev site), feel free to make PR for fixes and features 🙂

https://github.com/ceciletti/third-party-qt-utils

Facebook AccountKit with Qt/C++ on Android

Cutelyst 2.6.0 released! Now on VCPKG and buildroot

Cutelyst, a Qt Web Framework has upped to 2.6.0. This release is full of important bug fixes and is the best version when targeting Windows OS so far. It reached 5 years old, 440 stars on GitHub and since the last release has had many users asking questions, reporting issues and making pull requests.

Until now Windows support was a thing I mostly trusted Appveyor compiling and running tests fine, but this changed a bit in this release, I got a freelance job where some terminals would be editing images to be printed on T-Shirts, then they sent their art to a central server which receives and print, so, after I finished the QtQuick application and managed to convince them of running the terminals on KDE/Plasma as it was basically a kiosk full screen application I went on writing the server part.

Using Cutelyst on the server was a perfect match, the process was a Qt Widgets application, that, when linked to Cutelyst::WSGI could start listening all on the same process without issues, every terminal were connected via websockets protocol, which was just awesome, whenever I changed a terminal config I could see it changing instantly on the terminal, QWebSocketServer class could indeed do the same, but, to create the T-Shirt Art Fonts and Pictures needed to be “installed” on the terminal. Now with HTTP capabilities I simply exported all those folders and the whenever I sent a new JSON with config to the terminals, it contained the URLs of all these files which where updated in a blink.

On deploy time it was clear that using Windows on the server was a better option, first I’d need to give support for them on how to configure printers and use the system, also, printer drivers could also cause me troubles, so whatever let’s just compile it and get the money.

In order to make things easier I managed to get VCPKG to build a Qt5 for me, in a command line fashion, after that I saw how easy it was to create a package for Cutelyst, it’s upstream now, you just need to type:

vcpkg install cutelyst2

This will pull qt5-base package, and get you a working Cutelyst that easy, sadly Qt5 packages didn’t work on Linux nor on MacOS (both with issues filled).

Thanks to this project, several Windows related issues have been fixed, still work to do but I have an app on production on Windows now 🙂

I’m still no Windows fan, so I ended up configuring MXE and cross compiling Cutelyst and my application for Windows on Linux with it.

If you are doing embedded stuff, Cutelyst is also available on buildroot.

Besides that Cutelyst 2.6.0 has some other very important bug fixes.

Get it here!

Cutelyst 2.6.0 released! Now on VCPKG and buildroot

Virtlyst 1.2.0 released

Virtlyst – a Web Interface to manage virtual machines build with Cutelyst/Qt/C++ got a new release.

This new release includes a bunch of bug fixes, most importantly probably being the ability to warn user before doing important actions to help avoid doing mistakes.

Most commits came from new contributor René Linder who is also working on a Bootstrap 4 theme and Lukas Steiner created a dockerfile for it. This is especially cool because Virtlyst repository now has 4 authors while Cutelyst which is way older has only 6.

For the next release I’ll also try to add user management (today you have a single admin account, and to add new users that need to be done via SQL) which wasn’t available on the original WebVirtMgr project but is surely the most important lacking feature.

Have Fun! https://github.com/cutelyst/Virtlyst/archive/v1.2.0.tar.gz

Virtlyst 1.2.0 released

Cutelyst 2.5.0 released

Cutelyst a C++ web framework based on Qt got a new release. This release has some important bug fixes so it’s really recommended to upgrade to it.

Most of this release fixes came form a side project I started called Cloudlyst, I did some work for the NextCloud client, and due that I became interested into how WebDAV protocol works, so Cloudlyst is a server implementation of WebDAV, it also passes all litmus tests. WebDAV protocol makes heavy use of REST concept, and although it uses XML instead of JSON it’s actually a good choice since XML can be parsed progressively which is important for large directories.

Since the path URL now has to deal with file paths it’s very important it can deal well with especial characters, and sadly it did not, I had tried to optimize percent encoding decoding using a single QString instead of going back and forth toLatin1() then fromUTF8() and this wasn’t working at all, in order to better fix this the URL is parsed a single time at once so the QString path() is fully decoded now, which will be a little faster and avoid allocations. And this is now unit tested 🙂

Besides that there was:

  • Fix for regression of auto-reloading apps in cutelyst-wsgi
  • Fix csrf token for multipart/form-data (Sebastian Held)
  • Allow compiling WSGI module when Qt was not built with SSL support

The last one and another commit were to fix some build issues I had with buildroot, which I also created a package so soon you will be able to select Cutelyst from buildroot menu.

Have fun https://github.com/cutelyst/cutelyst/releases/tag/v2.5.0

Cutelyst 2.5.0 released

Cutelyst on TechEmpower benchmarks round 16

Yesterday TechEmpower released the results for round 16 of their benchmarking tests, you can see their blog about it here. And like for round 15 I’d like add my commentary about it here.

Before you look into the results web site it’s important to be aware of a few things, first round 16 runs on a new hardware newer and more powerful than the previous rounds, they also did a Dockerization of the tests which allowed us to pull different distro images, cache package install and isolate from other frameworks. So don’t try to compare to round 15.

Having put Cutelyst under testing there has brought many benefits to it, in previous rounds we noticed that due testing on a server with many CPU cores it letting the operating system do the scheduling wouldn’t be a good idea, so we added CPU affinity feature to cutelyst-wsgi, while uWSGI also has it our logic does this core pinning for threads and not only process.

While testing at home on an AMD Phenon II x4 using pre-fork mode was much faster than threaded mode, but on my 5th Gen Intel laptop the results were closer but threading was much better, and thanks to TFB I found out that each process were being assigned to CPU core 0, which made 28 processes be bound to a single core. In this new round you can now see the difference between running threaded or in pre-fork mode is negligible in some tests pre-fork is even faster. Pre-fork does consume more RAM, running 100 threads of Virtlyst uses around 35MiB, while 100 process around 130 MiB but multiple process are better if your code happens to crash.

An important feature of Tech Empower Benchmarks are it’s filters, they allow you to filter stuff that doesn’t matter to you, due the above fix you call look at the results and see the close threads vs pre-fork match here.

Using an HTML templating engine is very important for real world apps, in round 16 I’ve added a test that uses Grantlee for rendering, they are around 46% slower than creating the HTML directly on C++, there might be room for improvements in Grantlee but the fortunes results aren’t bad.

Some people asked why there were some many occurrences of Cutelyst in the tests, the reason is that these benchmarks allow you to tests some features and see what performs better, in round 15 it became clear that using EPoll vs Qt’s glib based event loop was a clear win, so in 16 we don’t have Qt’s glib tested anymore and EPoll is now the default event dispatcher in Cutelyst 2 on Linux.

This round however I tried to make a reasoning about TCP_NODELAY and while results are closer it’s a bit clear that due the blocking nature of the SQL tests TCP_NODELAY will decrease latency and increase performance a bit due it not waiting to send a bigger TCP packet.

As I also mentioned on the release of Cutelyst 2.4.0 a fix was made to avoid stack overflow and you can see the results on the “Plain Text” test, before that fix cutelyst was crashing and respawning and that limited the results to 1,000,000 requests/second, after the fix it is 2,800,000 requests/second.

This round used Ubuntu 18.04 as base, Cutelyst 2.4.0 and Qt 5.9.5.

Last but not least if you still try to compare to round 15 🙂 you might notice Cutelyst went lower on the ranking, that’s in part due frameworks getting optimizations but mostly due new micro/platform frameworks, but you can enable the Fullstack classification filter if you want to compare frameworks that would provide similar features that what Cutelyst offers.

Cutelyst on TechEmpower benchmarks round 16