[nginx] Fixed background requests with asynchronous operations.

Maxim Dounin mdounin at mdounin.ru
Thu Jul 27 08:54:25 UTC 2017


Hello!

On Mon, Jul 24, 2017 at 10:08:20AM +0000, Eran Kornblau wrote:

> Hi Roman,
> 
> I got a GitHub issue opened few days ago, that my module doesn't work following this commit -
> https://github.com/kaltura/nginx-vod-module/issues/645#issuecomment-317027706
> 
> The situation is as follows -
> 1. My module's content phase handler runs and performs an async read request -
> 	a. It calls ngx_file_aio_read which returns NGX_AGAIN
> 	b. Increments r->blocked
> 	c. Sets r->aio to 1
> 	(code here - https://github.com/kaltura/nginx-vod-module/blob/master/ngx_file_reader.c#L392)
> 2. The NGX_AGAIN status propagates up to ngx_http_core_content_phase which calls ngx_http_finalize_request
> 	with this status.
> 3. r->buffered, c->buffered, and r->postponed are all false, so this if:
> 	https://github.com/nginx/nginx/blob/master/src/http/ngx_http_request.c#L2456
> 	is skipped (it used to enter before the patch since r->blocked is 1)
> 	In addition, r == c->data, so at the end, ngx_http_finalize_request calls ngx_http_finalize_connection
> 4. Since r->main->count == 1 and r->keepalive == 1, this function calls ngx_http_set_keepalive
> 5. ngx_http_set_keepalive calls ngx_http_free_request which destroys the pool even though it has aio pending.
> 
> Please let me know if you think I'm doing something wrong here (I can, for example, increment r->main->count,
> but this is not done in any of the other places that do blocked++)

The NGX_AGAIN returned from a content phase handler when you 
started an AIO operation looks wrong: it means that nginx is 
already writing a response and was blocked by a full socket 
buffer.  In this case nginx will assume it should continue writing 
based on socket's write events, and will close the connection as 
long as everything is written (no r->buffered, c->buffered is 
set).  Before the Roman's patch the situation was the same: 
there is not r->blocking check in ngx_http_writer(), so it would 
close the connection as long as a write event happen for some 
reason.

Rather, you should use NGX_DONE and increment r->count if you want 
to wait for an AIO operation result and continue processing 
yourself.

[...]

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


More information about the nginx-devel mailing list