Git Product home page Git Product logo

Comments (9)

Kalileo avatar Kalileo commented on June 26, 2024

I can confirm this issue. I tried exactly the same, integrating the custom handler Mainhandler from the request-dumper example into the threads-with-router-example.
In other words, replacing the Tufao::HttpFileServer::handler("public") in router->map with this Mainhandler.
Same result as kingctan, crash. Interestingly most of the time not at the first browser request, but at the 2nd.

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    TcpServer server;

    server.run(4, 8080, []() {
        QSharedPointer<Tufao::HttpServerRequestRouter> router;
        MainHandler h;

        return [router](Tufao::HttpServerRequest &request,
                        Tufao::HttpServerResponse &response) mutable {
            if (!router) {
                router.reset(new Tufao::HttpServerRequestRouter);
                router->map({QRegularExpression{"^/([^/]+)"}, h});
            }

            if (!router->handleRequest(request, response)) {
                response.writeHead(Tufao::HttpResponseStatus::NOT_FOUND);
                response.headers().insert("Content-Type", "text/plain");
                response.end("404 Not found.\n");
            }

            return true;
        };
    });

    return a.exec();
}

Reducing to 1 worker thread ("server.run(1, 8080...") did not help.
The original example threads-with-router-example works fine, as well as all the other examples.

Unfortunately this is a showstopper.

Is there something wrong with this approach?
Or is there any other way to run multiple workers / threads and custom handlers?

from tufao.

Kalileo avatar Kalileo commented on June 26, 2024

Qt 5.5.1 on Mac OS X (deployment will be on Linux though).

from tufao.

Kalileo avatar Kalileo commented on June 26, 2024

Tested on linux, and the same problem, crashing as soon as a Url is requested which matches the QRegularExpression - unlike on Mac, where the first request still works.

There is some debug output on linux, when it crashes:

pure virtual method called
terminate called without an active exception
The program has unexpectedly finished.

Valgrind does not give more output than that.

In QtCreator, run in debug mode, this is where it stands after crashing:

inline AbstractHttpServerRequestHandler::operator
std::function<bool(HttpServerRequest&, HttpServerResponse&)>()
{
    return [this](HttpServerRequest &req, HttpServerResponse &res) {
        return this->handleRequest(req, res);
    };   <<=== here
}

I hope that gives enough info to fix it. Otherwise please ask.

from tufao.

Kalileo avatar Kalileo commented on June 26, 2024

As a humble workaround, while waiting for the official fix, you can move the functionality of the lambda in main() at server.run(4, 8080, {...}) to the Worker class, eliminating all Factory() and setFactory() stuff in Worker and TcpServer, as well as the router. Then it works multithreaded.

Main changes below:

In main.cpp :

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    TcpServer server;
    server.run(4, 8080);
    return a.exec();
}

In worker.cpp call myHandler(*request, *response); instead of handler(*request, *response); :

bool Worker::myHandler(HttpServerRequest &request,
                       HttpServerResponse &response)
{
    const QString path(request.url().path());
    QRegularExpression re = QRegularExpression("^/([^/]+)......."); // change to what you need
    QRegularExpressionMatch match(re.match(path));

    if (request.method() == "GET" && match.hasMatch())
    {
        QStringList args{match.capturedTexts().mid(1)};
        QVariant backup{request.customData()};

        if (args.size()) {
            QVariantMap options{backup.toMap()};
            options["args"] = options["ags"].toStringList() + args;
            request.setCustomData(options);
        }

        // defined in worker.h:  MainHandler h;

        if (h.handleRequest(request, response))
            return true;

        if (args.size())
            request.setCustomData(backup);
    }

    response.writeHead(Tufao::HttpResponseStatus::NOT_FOUND);
    response.headers().insert("Content-Type", "text/plain");
    response.end("404 Not found.\n");

    return true;
}

It might be nice to get the router functionality back in, I skipped that here in favour of a simple workaround.

imho having the handler code in the worker instead of in main is not less efficient, with the lambda in main and the setFactory stuff it ends up there anyway.

from tufao.

vinipsmaker avatar vinipsmaker commented on June 26, 2024

Mainhandler from the request-dumper example into the threads-with-router-example.

It inherits QObject. You should not copy them, but you created them in the beginning of the block and copied it during the map call? Just a hint about what might be happening.

while waiting for the official fix

This is a malformed combination of two different examples. I don't claim an abstraction here being thread-safe when it's not. Examples are learning material to speedup your understanding. Not sure what to fix here.

from tufao.

Kalileo avatar Kalileo commented on June 26, 2024

You should not copy them, but you created them in the beginning of the block and copied it during the map call?

Yes, see first code sample above.

a malformed combination of two different examples.

What would be a better example to combine the threads-with-router-example and handlers? I think such a combination is needed for any server doing more than just serving a few more or less static files or bytes of html. Especially also when handling file uploads.

Not sure what to fix here.

There might be nothing to fix in the server code, but just to show the correct way of doing it, an example for this not so uncommon use case.

Also I think that you laid the foundation to a beautiful server. I've played around with some handlers for our main use cases, and it's fun and easy.

from tufao.

vinipsmaker avatar vinipsmaker commented on June 26, 2024

There might be nothing to fix in the server code, but just to show the correct way of doing it, an example for this not so uncommon use case.

That's a starting point. Thanks.

from tufao.

Kalileo avatar Kalileo commented on June 26, 2024

Just to make sure that the issue reported here is not misunderstood as a general problem with Tufao: a multithreaded server application with router and many handlers, based on the code as I posted it above, is currently in production test and so far no issues at all, rock solid, without a single change or issue in the Tufao code, and faaaast!
@vinipsmaker / Vinícius dos Santos Oliveira: Big thanks for Tufao!

from tufao.

vinipsmaker avatar vinipsmaker commented on June 26, 2024

Big thanks for Tufao!

You're welcome

from tufao.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.