cpprestsdk icon indicating copy to clipboard operation
cpprestsdk copied to clipboard

Setting the number of workers for http_listener

Open nickaein opened this issue 5 years ago • 3 comments

Is there any way to set the number of workers forhttp_listener? I've tried

 crossplat::threadpool::initialize_with_threads(8);

as suggested for http client (#883, #704). While it seems to limit the number of spawned threads for the request, the server gets blocked after serving accepting a few requests and doesn't process new ones.

Here is the trimmed down version of my code:

int HttpServer::start_listen()
{
    crossplat::threadpool::initialize_with_threads(8);

    listener = listener::http_listener(uri);
    listener.support(methods::GET, std::bind(&HttpServer::handle_get, this, std::placeholders::_1));
    listener.support(methods::POST, std::bind(&HttpServer::handle_get, this, std::placeholders::_1));

    listener.open().wait();
    std::this_thread::sleep_for(std::chrono::seconds(100000));
}


void HttpServer::handle_get(web::http::http_request message)
{
    std::string request_body = message.extract_string(true).get();

    // this spawns a couple of threads that perform heavy
    // computations which would take  around 1000ms
    std::string response_body = process_message(request_body);

    message.reply(status_codes::OK, response_body);
}

nickaein avatar Jul 31 '19 15:07 nickaein

See e.g. https://github.com/microsoft/cpprestsdk/issues/1147#issuecomment-499414735

garethsb-ghost avatar Jul 31 '19 22:07 garethsb-ghost

Thanks! This fixed the issue. But why this happens only when all threads become busy? Isn't this a deficit in design that the scheduler chokes when all working threads are busy? Shouldn't it keep a worker thread reserved for housekeeping?

Nevertheless, I've rewritten the code as following and the issue seems to be fixed. Is this in spirit of the library and have correct design?

void HttpServer::handle_get(web::http::http_request message)
{
    // capture message by value (capturing by reference causes segfault)
    message.extract_string(true).then([&, message](pplx::task<std::string> t) {
        request_body = t.get();
        handle_get_internal(request_body, message);
    });
}

void HttpServer::handle_get_internal(std::string request_body, web::http::http_request message)
{
    // a dozen of lines that handle various cases for message
    // request and eventually call message.reply() with a suitable
    // HTTP code and body like the following:

    message.reply(status_codes::OK, response_body);
}

nickaein avatar Aug 03 '19 11:08 nickaein

If i had to wait for some response and perform further steps only after the request is completed, then what to do in that case . Also many cpprest blogs demonstrate to wait on the request object.

https://mariusbancila.ro/blog/2017/11/19/revisited-full-fledged-client-server-example-with-c-rest-sdk-2-10/

Below is my code snippet and it seems to work for first few requests and then hangs and it retrieves after few minutes . I dnt have access to server side code and seems server side code is there for many years. I am just writing the client side code

pplx::task<web::http::http_response> request_task = client.request(request);
        try
        {        
            web_response = request_task.get();
            result = true;

        }
        catch (const std::exception& ex)
        {
            string_t errorMessage;
            ErrorMsg = L"Can't reach the confighub agent. " + utility::conversions::to_string_t(ex.what());
        }
        catch (...)
        {
            return result;
        }

@nickaein can you pls tell you changed the code at client side or server side.

sahnnu avatar Aug 08 '22 12:08 sahnnu