libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] large incremental responses


From: Evgeny Grin
Subject: Re: [libmicrohttpd] large incremental responses
Date: Sat, 4 Dec 2021 17:19:45 +0300
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.3.2

Hi Erik,

The response transmission speed is determined by two factors:
1. Now quick data is consumed by remote side,
2. Now quick data can be produced.

You cannot just produce data by portions, you need to check whether remote side is ready to get next piece of data. It doesn't matter how slow you produce the data: even if you produce one byte per minute the remote side still can consume it slower.

If you don't want to check readiness of the remote side, you need to implement buffering.

I can suggest several alternatives.
a. Use thread pool for MHD. When data callback is called, suspend connection and trigger generation of the *requested amount* of the data. When data is generated (you must detect this moment by callback or by some polling or monitoring) resume connection. Data callback is called again by MHD, and you can feed MHD all generated data. No need to complex buffering, the single fixed-size buffer can be reused. MHD cannot request data more than MHD_OPTION_CONNECTION_MEMORY_LIMIT. b. Use thread-per-connection for MHD. For each request create a new response object by MHD_create_response_from_pipe(). Write response data to the pipe, but you need to monitor pipe for write readiness.

--
Evgeny

On 03.12.2021 20:40, Erik Smith wrote:
Hi Evgeny,

That's mostly how I understood it from past experience.  To use that directly, it does require that my producer logic be written in a callback style: like a state function that's producing a chunk of content at a time. Secondly it must only send up to max bytes, which will require buffer management.   So this does complicate that logic when compared to the synchronous thread-per-request style.   My near term option appears to be to use a worker thread that writes content into a buffer with the appropriate concurrency control.  Eventually I would like to adopt a fiber approach and it would be good to know if anyone has experience with that.

Erik

    Hi Erik,
    You need to create response by MHD_create_response_from_callback().
    Use 'MHD_SIZE_UNKNOWN' if size is not known in advance. When data
    callback is called by MHD, provide all data you have at that moment
    (but not more than requested by MHD of course). If you don't have
    any data available call MHD_suspend_connection(). Later, when you
    get new portion of data ready to send, call MHD_resume_connection()
    then data callback will be called automatically by MHD.
    Does it suit your needs?
    --
    Evgeny
    On 02.12.2021 21:53, Erik Smith wrote:

    If I want to send a large response that takes time to generate and
    have the response sent incrementally in a push style (regular write
    calls in synchronous code, not callbacks) so that the client doesn't
    time out, how would I do that?  Is that something I'm going to have
    to write some concurrency mechanism for so that I can use a callback
    or is there a simpler way?


Attachment: OpenPGP_signature
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]