CrowCpp / Crow

A Fast and Easy to use microframework for the web.
https://crowcpp.org
Other
3.24k stars 355 forks source link

Question of async or blocking #928

Closed witcherofthorns closed 5 days ago

witcherofthorns commented 1 week ago

Hi everyone, I wanted to ask something about Crow, I still continue to write an application in Crow and everything is fine, I even released it for production testing on real clients, but I have a question that bothers me Did I understand correctly that Crow provides a separate thread from std::async for each http request? That is, I can safely call what I want and how I want, without using a mutex lock?

CROW_ROUTE(app, "/api/user", HTTPMethod::GET)([&](const request& req){
    // check req functional or middlevares 
    // other some functional
    return UserRepository::Get(...) 
        ? response(OK, "application/json", json)
        : response(NO_CONTENT);
});

In this case i am calling a static method in a static class that is stateless and uses the mongocxx connection pool

bool UserRepository::Get(const std::string& oid, Models::User& return_user){
    // get connection from pool mongodb driver
    auto conn = mongo->acquire();
    // mongodb some functional
    // return user model
    return true;
}

But it seems to me that if I use a mutex lock, something can go wrong, and whether it is necessary to use it at all or not, if different threads will access the same global resource, where in theory a connection pool is used - i.e. does not lock and does not share the connection state, each connection is unique

bool UserRepository::Get(const std::string& oid, Models::User& return_user){
    // mutex lock
    std::lock_guard<std::mutex> lock(mutex);
    // get connection from pool mongodb
    auto conn = mongo->acquire();
    // mongodb some functional
    // return user model
    return true
}

My question is not related to mongodb, my question is related to call security in async environment (if you can call it that), i have not encountered any errors in Crow, but the thing is that i have not had a large number of requests/clients yet, but very soon there may be 100+ per second and i just want to be on the safe side, i haven't worked much with async runtime, maybe I don't understand something or forgot something, maybe get some useful feedback, let me know, because as I said earlier, I like Crow and I would like to release on, thanks for your attention

gittiver commented 5 days ago

Request handlers can potentially run in separate threads. That means that you have to protect shared resources potentially.

That may be done on handler level or maybe on the level of abstracted resources (I would call it model level). In case of a database handle it's probably a global lock. But it seems that mongoldb has its own locking inside (->acquire).

witcherofthorns commented 5 days ago

hi @gittiver , thanks for the answer, well, if I can figure out the stability of asynchrony in Crow - then I will finish the project on it, in any case I will still try to release it in real production and watch its behavior, let's see what comes of this