[Interest] QtHttpServer Asynchronous Request Processing

Daniel hein.dnl at gmail.com
Wed Jan 4 17:31:28 CET 2023


Hi all,

I played around with the new QHttpServer module in Qt6.4.1 and Qt6.5 and
ran into some questions regarding how to implement an asynchronous request
processing. I would like to implement a webservice that can handle several
requests in parallel, since each request may take significant processing
time to generate the corresponding response.

Some examples in the following using QHttpServer:

    QHttpServer server;
    server.route("/", []() {
    return QtConcurrent::run([]() {
                std::cout <<
QTime::currentTime().toString().toLatin1().constData() << " start" <<
std::endl;
                QThread::currentThread()->msleep(5000); //simulate some
processing time
                std::cout <<
QTime::currentTime().toString().toLatin1().constData() << " stop" <<
std::endl;
                return QHttpServerResponse(QString("1"));
                });
        });
    server.listen(QHostAddress::Any, 80)

When I run this example on a Windows machine and generate requests from two
different browser windows to "http://127.0.0.1", the registered view
handler lambda is processed in sequence and not (as expected) in parallel
(i.e. I get start/stop/start/stop). This is the same behavior with Qt6.4.1
as with Qt6.5.

However, I could observe a different behavior, if I register a second rule:

    QHttpServer server;
    server.route("/", []() {
        return QtConcurrent::run([]() {
                std::cout <<
QTime::currentTime().toString().toLatin1().constData() << " start" <<
std::endl;
                QThread::currentThread()->msleep(5000); //simulate some
processing time
                std::cout <<
QTime::currentTime().toString().toLatin1().constData() << " stop" <<
std::endl;
                return QHttpServerResponse(QString("1"));
                });
        });
    server.route("/", [](QString id) {
            return QtConcurrent::run([id]() {
                std::cout <<
QTime::currentTime().toString().toLatin1().constData() << " start" <<
std::endl;
                QThread::currentThread()->msleep(5000); //simulate some
processing time
                std::cout <<
QTime::currentTime().toString().toLatin1().constData() << " stop" <<
std::endl;
                return QHttpServerResponse(QString("2: %1").arg(id));
                });
            });
    server.listen(QHostAddress::Any, 80)

Surprisingly, if I now enter in the first browser window "http://127.0.0.1"
while in the second browser window "http://127.0.0.1/test", both view
handlers are processed in parallel, i.e. I get start/start/stop/stop. So,
different view handlers can be run in parallel, if their (different) rules
are fired at the same time. Thus, in general an asynchronous request
processing is obviously possible, but unfortunately with the current API
and implementation only for different targets / rules.

Since I need to handle arbitrarily formed URL requests (that does not fit
into the current route-API of QHttpServer), I tried similar experiments
using QAbstractHttpServer and overriding the handleRequest() function. Here
again, I could not find a way for an asynchronous request processing, i.e.
early return of handleRequest() function after triggering asynchronous
background jobs for each request, and then later sending the calculated
response. Every handleRequest() is called only after the response to the
last request was sent.

Furthermore, the handleRequest() interface looks like it expects to send
the response within this function (blocking call). The interface even
changed from Qt6.4.1 to Qt6.5, and in Qt6.5 with the non-copyable
QHttpServerResponder parameter it is even harder to keep this struct for a
later response (only by std::moving).

So, my question is, if QHttpServer is intended to support asynchronous
request processing (for arbitrary URL requests) sometime in the future? Or
am I missing the correct way to do this with the current API?

Thanks in advance
Daniel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20230104/3b7c058d/attachment.htm>


More information about the Interest mailing list