[PATCH 2 of 4] Simplified sendfile_max_chunk handling
Sergey Kandaurov
pluknet at nginx.com
Wed Oct 27 14:19:19 UTC 2021
> On 11 Oct 2021, at 21:58, Maxim Dounin <mdounin at mdounin.ru> wrote:
>
> # HG changeset patch
> # User Maxim Dounin <mdounin at mdounin.ru>
> # Date 1633978587 -10800
> # Mon Oct 11 21:56:27 2021 +0300
> # Node ID 489323e194e4c3b1a7937c51bd4e1671c70f52f8
> # Parent d175cd09ac9d2bab7f7226eac3bfce196a296cc0
> Simplified sendfile_max_chunk handling.
>
> Previously, it was checked that sendfile_max_chunk was enabled and
> almost whole sendfile_max_chunk was sent (see e67ef50c3176), to avoid
> delaying connections where sendfile_max_chunk wasn't reached (for example,
> when sending responses smaller than sendfile_max_chunk). Now we instead
> check if there are unsent data, and the connection is still ready for writing.
> Additionally we also check c->write->delayed to ignore connections already
> delayed by limit_rate.
>
> This approach is believed to be more robust, and correctly handles
> not only sendfile_max_chunk, but also internal limits of c->send_chain(),
> such as sendfile() maximum supported length (ticket #1870).
>
> diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c
> --- a/src/http/ngx_http_write_filter_module.c
> +++ b/src/http/ngx_http_write_filter_module.c
> @@ -321,16 +321,12 @@ ngx_http_write_filter(ngx_http_request_t
> delay = (ngx_msec_t) ((nsent - sent) * 1000 / r->limit_rate);
>
> if (delay > 0) {
> - limit = 0;
> c->write->delayed = 1;
> ngx_add_timer(c->write, delay);
> }
> }
>
> - if (limit
> - && c->write->ready
> - && c->sent - sent >= limit - (off_t) (2 * ngx_pagesize))
> - {
> + if (chain && c->write->ready && !c->write->delayed) {
> ngx_post_event(c->write, &ngx_posted_next_events);
> }
>
Looks good.
Not strictly related to this change, so FYI. I noticed a stray writev()
after Linux sendfile(), when it writes more than its internal limits.
2021/10/27 12:44:34 [debug] 1462058#0: *1 write old buf t:0 f:1 0000000000000000,
pos 0000000000000000, size: 0 file: 416072437, size: 3878894859
2021/10/27 12:44:34 [debug] 1462058#0: *1 http write filter: l:1 f:0 s:3878894859
2021/10/27 12:44:34 [debug] 1462058#0: *1 http write filter limit 0
2021/10/27 12:44:34 [debug] 1462058#0: *1 sendfile: @416072437 2147482891
2021/10/27 12:44:34 [debug] 1462058#0: *1 sendfile: 2147479552 of 2147482891 @416072437
2021/10/27 12:44:34 [debug] 1462058#0: *1 writev: 0 of 0
2021/10/27 12:44:34 [debug] 1462058#0: *1 http write filter 0000561528695820
2021/10/27 12:44:34 [debug] 1462058#0: *1 post event 00005615289C2310
Here sendfile() partially sent 2147479552, which is above its internal
limit NGX_SENDFILE_MAXSIZE - ngx_pagesize. On the second iteration,
due to this, it falls back to writev() with zero-size headers.
Then, with the patch applied, it posts the next write event, as designed
(previously, it would seemingly stuck instead, such as in ticket #1870).
--
Sergey Kandaurov
More information about the nginx-devel
mailing list