Copyright © https://mongoose-os.com

Mongoose OS Forum

frame

multithreading web server

CarlesBolañosCarlesBolaños Barcelona

Hello

I'm trying to develop a multithread webserver. Some requests take long computation time and other calls need to be blocked. On an old forum a found this solution:

  1. A very high performance (e.g. millions of requests / second) is required. Then, on multicore machine, each core can be given a copy of a listening socket and it's own mongoose context.

Can you show me a sample. I don't know exactly how to copy the listening socket, and what exactly is a mongoose context.

Thanks a lot

Comments

  • @CarlesBolaños said:
    Hello

    I'm trying to develop a multithread webserver. Some requests take long computation time and other calls need to be blocked. On an old forum a found this solution:

    1. A very high performance (e.g. millions of requests / second) is required. Then, on multicore machine, each core can be given a copy of a listening socket and it's own mongoose context.

    Can you show me a sample. I don't know exactly how to copy the listening socket, and what exactly is a mongoose context.

    Thanks a lot

  • SergeySergey Dublin, Ireland

    We don't have an example for this at the moment, but the actions should be like this:

    • on MG_EV_HTTP_REQUEST, a connection handler must pass computational task to the working thread, together with the connection identifier. No reply should be returned to the user.
    • when a working thread is done, it should call mg_broadcast(). in the data, it should send an ID of the connection and computation results. 8k maximum.
    • in the broadcast handler function, iterate over the connections, find the one with matching IDs (don't use connection pointers!), and send the reply back to the user.
  • edited October 2017

    What if computational task returns some complicated data like
    struct ComplicatedData {
    std::string charData[123];
    int* intData[456];
    VeryComplicatedData omg[789];
    }

    And you need to handle it differently for each connection. It could be a pain to serialize such data to 8k buffer. Or 8k buffer might not be enough.

    I wish there was some method that would trigger internal event like MG_EV_POLL but only once. mg_broadcast() can do this, but triggers for each connection and you must send something in the buffer.

  • SergeySergey Dublin, Ireland

    Could you elaborate on the MG_EV_POLL suggestion please? I did not fully get it.

    The problem is how to pass the data to the IO thread.
    Currently mg_broadcast () simply copies the data - problem solved.
    If the data is not copied, there should be a locking dance.

  • edited October 2017

    Here is my suggestion. Not sure that is the best one.

    mg_mgr mMgr;
    mutex mtx;
    queue<ComplicatedData> dataQueue;
    
    // Inside computational task
    void  computational_task() {
    
    ComplicatedData data;
    
    mtx.lock();
    dataQueue.push(data);
    mtx.unlock();
    
    mg_trigger_somewhere_inside_mongoose_mgr_poll(&mMgr, &somewhere_inside_mongoose_mgr_poll, &user_data);
    }
    
    // Inside mongoose mg_mgr_poll()
    void somewhere_inside_mongoose_mgr_poll(void * user_data) {
    mtx.lock();
                while (! dataQueue.empty()) {
                    ComplicatedData data = dataQueue.front();
    
                    /* Run through connection list and handle data differently for each connection.  */
    
                    dataQueue.pop();
                }
    mtx.unlock();
    }
    
Sign In or Register to comment.