[PATCH][bugfix] Upstream: clear the delayed flag to prevent blocking from sending.

Maxim Dounin mdounin at mdounin.ru
Sun Apr 2 13:35:55 UTC 2017


Hello!

On Fri, Feb 17, 2017 at 11:18:48AM +0800, 胡聪 (hucc) wrote:

> Hi,
> 
> To reproduce the scene of send blocking, there must be more than twosubrequest, and the more the better.
> 
> 
> When I encounter this problem, my config is as follows (roughly):
>  slice                       1M;
> limit_rate                2M;
> proxy_buffering       on
> proxy_buffer_size    32K;
> proxy_buffers    4    64K;
> proxy_pass       http://domain/uri;
> 
> 
> And my system:
> Linux ** 2.6.32-642.13.1.el6.x86_64 #1 SMP Wed Jan 11 20:56:24
> UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
> 
> 
> Patchs bellow:
> 
> # HG changeset patch
> # User hucongcong <hucong.c at foxmail.com>
> # Date 1487298087 -28800
> #      Fri Feb 17 10:21:27 2017 +0800
> # Node ID 37b376790ecf83eaaff2f024eb3093a079091d93
> # Parent  05fd0dc8f0dc808219f727dd18a5da2f078c4073
> Upstream: clear the delayed flag to prevent blocking from sending.
> 
> Suppose that proxy_buffering is on and limit_rate is defined, the send will be
> blocked in write filter when the following two conditions are met: First, the
> previous upstream request sets the write->delayed flag and starts the timer of
> downstream, and then finalized. Second, the timer timed out before the next
> subrequest enters the function ngx_http_upstream_send_response(), which means
> the delayed flag is not be cleared properly. Thus, the data transmission from
> upstream to downstream will be blocked in subrequest.
> 
> By clearing the delayed flag of c->write in ngx_http_upstream_send_response()
> when the timer of write event is deleted, to solve this problem.
> 
> diff -r 05fd0dc8f0dc -r 37b376790ecf src/http/ngx_http_upstream.c
> --- a/src/http/ngx_http_upstream.c	Thu Feb 16 18:37:22 2017 +0300
> +++ b/src/http/ngx_http_upstream.c	Fri Feb 17 10:21:27 2017 +0800
> @@ -2848,6 +2848,10 @@ ngx_http_upstream_send_response(ngx_http
>  
>      c = r->connection;
>  
> +    if (c->write->delayed && !c->write->timer_set) {
> +        c->write->delayed = 0;
> +    }
> +
>      if (r->header_only) {
>  
>          if (!u->buffering) {

Thank you for your report.

After looking into this for a while, I've committed several 
patches to fix various issues with wev->delayed:

http://hg.nginx.org/nginx/rev/7fcf209d40c8
http://hg.nginx.org/nginx/rev/1c5e5e5b008d
http://hg.nginx.org/nginx/rev/903fb1ddc07f

-- 
Maxim Dounin
http://nginx.org/


More information about the nginx-devel mailing list