Copyright © https://mongoose-os.com

Mongoose OS Forum

frame
ATTENTION! This forum has moved to:

https://community.mongoose-os.com

Do not post any new messages.

Non-blocking query handling

What scope is there within Mongoose for custom non-blocking query handling. For example, a HTTP POST request comes in, requiring a few seconds calculation before the response can be generated. Ideally I would send a message to another program thread, allowing the event handler to serve other queries, and get the other thread to provide the response via a callback or similar mechanism.

Comments

  • Any comments here from the developers would be welcome.

  • SergeySergey Dublin, Ireland

    The easiest way is to spawn a thread per request:
    https://github.com/cesanta/mongoose/tree/master/examples/multithreaded_restful_server

    If you'd like to keep it single-threaded, that is also perfectly possible, but must be done manually. Can you elaborate on your use case please?

  • Hi Sergey, thanks a lot for your reply. It's good to see there's support for this.

    Maybe you could describe the single-threaded mechanism a bit?

    Here is my use-case: when POST request "/compute" is received, my application must perform a processor-intensive task, and give the response back to the client; this takes on order of a couple of seconds. This intensive task is carried out over several CPU cores to minimize the computation time. If two clients simultaneously request "/compute", then one of them will have to wait; this is unavoidable. But if only one client requests "/compute", then I would like Mongoose to still serve static files to other clients without blocking.

  • SergeySergey Dublin, Ireland

    Thanks for elaborating on this. As I said, there multiple ways to do it. One way is to keep serving core single-threaded and use mg_broadcast() API function. Here is a signature:

    /*
     * Passes a message of a given length to all connections.
     *
     * Must be called from a thread that does NOT call `mg_mgr_poll()`.
     * Note that `mg_broadcast()` is the only function
     * that can be, and must be, called from a different (non-IO) thread.
     *
     * `func` callback function will be called by the IO thread for each
     * connection. When called, the event will be `MG_EV_POLL`, and a message will
     * be passed as the `ev_data` pointer. Maximum message size is capped
     * by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes.
     */
    void mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t);
    

    The sequence of actions is this:

    • When /compute POST request is received, pass computation parameters to another thread. Pass some ID to identify current connection.
    • When computation is finished, call mg_broadcast. Pass that ID and computation -results in the message.
    • In the callback function, check the current connection by comparing the ID. If you're on a connection that is waiting for the result, fetch the result from the message and send the reply back to the client.

    Could you elaborate more on your project please? Is it personal or commercial?

  • Sergey, thanks a lot for these details. It is a commercial project, we have purchased a licence and we pay the support fee. I will try to implement it as you suggest, I'll let you know if I have difficulties.

  • SergeySergey Dublin, Ireland

    Ah, I see, Jamie! Sure thing, let me know how it goes :-)

Sign In or Register to comment.