[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?
OpenPGP_signature
Description: OpenPGP digital signature