2 questions on send_timeout (maybe bugs)

Maxim Dounin mdounin at mdounin.ru
Wed May 18 17:35:07 MSD 2011


Hello!

On Wed, May 18, 2011 at 05:15:00PM +0800, Wu Bingzheng wrote:

> hi all,
> 
> 
> I meet 2 question when using nginx 1.0.0.
> 
> 
> Question1.
> 
> what happens if the downstream connection breaks, before all 
> data sent to the client?
> 
> 1. get client's request
> 2. set handler: r->read_event_handle=ngx_http_block_reading
> 3. send data to client, and blocked ( 
> write_filter.c:c->send_chain() returns non-NULL or non-error), 
> and go back to epoll_wait
> 4. HERE, the downstream breaks
> 5. epoll detect the breaking, so epoll_wait() continues in 
> ngx_epoll_process_events(), where the revents==EPOLL_IN | 
> EPOLL_ERR | EPOLL_HUP. So we call rev->handler(), which calls 
> r->read_event_handle, which dose nothing. AS A RESULT, the 
> downstream breaking was not detected by nginx !!!

Here write event handler will be called.  While standard 
ngx_http_writer() is in use - it will call output filter chain and 
detect error.  Else it's up to active handler to correctly handle 
this, e.g. standard upstream modules (proxy/fastcgi/...) may 
either terminate request immediately or wait for full upstream 
response depending on various settings (proxy_ignore_client_abort, 
proxy_cache/proxy_store enabled).

> 6. Then, we have to wait for send_timeout...
> 
> This situation dosenot occur everytime. If the downstream 
> breaks, when nginx is sending data, the breaking will be 
> detected.
> But I can make this happen all the time, when:
> 1. the client and server are far away from each other (e.g. not 
> in a local net)
> 2. using memc module
>
> Question2.
> 
> I set 'send_timeout' as 20s, but nginx timeouts in 40s actually.
> 
> 1. in 
> src/http/ngx_http_upstream.c[line2448]:ngx_http_upstream_process_non_buffered_request(), 
> a timer is added;
> 2. after that timer timeout, in 
> src/http/ngx_http_request.c[line2179]:ngx_http_set_write_handler(), 
> another timer is added again.
> 
> so the send_timeout is doubled.

Timeout is re-set on each send operation, and expected to be 
triggered when nothing happens during send_timeout.

Maxim Dounin



More information about the nginx mailing list