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