handle NGX_AGAIN properly
Julien Zefi
jzefip at gmail.com
Sat Jul 13 23:43:22 UTC 2013
Hi,
On Tue, Jul 9, 2013 at 7:02 PM, Yichun Zhang (agentzh) <agentzh at gmail.com>wrote:
> Hello!
>
> On Tue, Jul 9, 2013 at 5:12 PM, Julien Zefi wrote:
> > But if in some triggered callback by the timer the
> > ngx_http_output_filter(..) returns NGX_AGAIN *i assume* NginX will send
> that
> > chain as soon as the socket becomes available again.
>
> This assumption is not correct. Nginx will only flush out the pending
> data for you when r->write_event_handler is set to ngx_http_writer.
> This only (automatically) happens in ngx_http_finalize_request (by
> calling the ngx_http_set_write_handler function to do the assignment
> to r->write_event_handler).
>
> > But after that happens,
> > how can i restore my timer cycle ?
> >
>
> My suggestion is to register your own r->write_event_handler handler
> to propagate the pending outputs by calling ngx_http_output_filter
> with a NULL chain link pointer yourself. And in that handler, you can
> also restore your timer cycle and etc when all the pending outputs
> have been flushed out (into the system socket send buffers).
>
> I've been doing something like this in our ngx_lua module. You can
> check out the ngx.flush() API function's implementation in particular:
>
> http://wiki.nginx.org/HttpLuaModule#ngx.flush
I have been trying many workarounds without luck, the last one that i have
is that if in my timer-callback the flush returns NGX_AGAIN, invoke a new
handler that sends out an empty chain, but it continue returning NGX_AGAIN,
it never backs to NGX_OK, this is how it looks:
306 static void ngx_http_hls_flush(ngx_event_t *e)
307 {
308 printf("Trying to flush data\n");
309 int ret;
310 ngx_buf_t *buf;
311 ngx_chain_t chain;
312 ngx_http_request_t *r;
313 ngx_http_hls_event_t *hls_event;
314
315 hls_event = e->data;
316 r = hls_event->r;
317
318 buf = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
319 buf->pos = NULL;
320 buf->last = NULL;
321 buf->memory = 0;
322 buf->last_buf = 1;
323
324 chain.buf = buf;
325 chain.next = NULL;
326
327 ret = ngx_http_output_filter(r, &chain);
328 if (ret == NGX_OK) {
329 e->handler = ngx_http_hls_timer;
330 }
331 else if (ret == NGX_AGAIN) {
332 e->handler = ngx_http_hls_flush;
333 }
334 else {
335 e->handler = ngx_http_hls_finalize;
336 }
337
338 ngx_add_timer(e, 50);
339 }
it always returns to hgx_http_hls_flush, what else i can do ?, i have spent
bunch of hours on this, any extra help is welcome.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20130713/957997cf/attachment.html>
More information about the nginx-devel
mailing list