<div dir="ltr">Maxim - thank you for your helpful response.  I will review the memcached module.<div><br></div><div>In the meantime, I had tried a few things and ended up with the following approach (as a rough example):</div>
<div><br></div><div><div>static ngx_int_t content_phase_handler(ngx_http_request_t *r) {</div><div>    ...</div><div>    /* some function that returns AGAIN or OK to either wait or proceed */</div><div>    rc = function();</div>
<div>    if (rc == NGX_AGAIN) {</div><div>        r->main->count++;</div><div>        ctx->ev.handler = event_handler;</div><div>        ctx->ev.data = r;</div><div>        ctx->ev.log = r->connection->log;</div>
<div>        ngx_add_timer(&ctx->ev, 100);</div><div>        return NGX_DONE;</div><div>    }</div><div><br></div><div>    ...normal work of content phase handler...</div><div>}   </div><div><br></div><div>static void event_handler(ngx_event_t *ev) {</div>
<div>    ngx_http_request *r;</div><div>    r = ev->data;</div><div>    r->write_event_handler = ngx_http_core_run_phases;</div><div>    ngx_http_core_run_phases(r);</div><div>    return;</div><div>}</div></div><div>
<br></div><div><br></div><div>I had noticed from the DEBUG log output sequence that nginx_finalize_request() was getting called after NGX_DONE was returned from the content phase handler.  From the source, nginx_finalize_request() called nginx_http_finalize_connection() if (r->main->count != 1), which then called nginx_http_close_request() which decremented the count and returned without freeing the req or closing the connection.</div>
<div><br></div><div>So, it seems like some of what you've recommended (incrementing req count, and having finalize_request called) is then being done.</div><div><br></div><div>This seemed to work correctly and each time the event handler triggered, the content phase handler was called again.  However, is calling core_run_phases() a poor/dangerous approach or not recommended?</div>
<div><br></div><div>Also, is there a recommended lower bound for the millisecond timer?  For example, don't make it smaller than X ms, otherwise the event cycle gets run too frequently?</div><div><br></div><div>Thanks,</div>
<div><br></div><div>Ben</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jun 2, 2014 at 9:26 AM, Maxim Dounin <span dir="ltr"><<a href="mailto:mdounin@mdounin.ru" target="_blank">mdounin@mdounin.ru</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello!<br>
<div><div class="h5"><br>
On Fri, May 30, 2014 at 02:27:36PM -0700, <a href="mailto:bfranks781@gmail.com">bfranks781@gmail.com</a> wrote:<br>
<br>
> If a content phase handler needs to wait on some potentially delayed<br>
> result, my understanding is that it should return NGX_DONE so that it is<br>
> called again.<br>
><br>
> I've been reading through the eval, echo, and http_limit_req modules to see<br>
> how to integrate an nginx_add_timer event prior to returning NGX_DONE.  A<br>
> short timer event seems reasonable, because the content phase handler isn't<br>
> waiting on some other event type (subrequest result, timeout, etc).  The<br>
> timer event seems fairly straight-forward -- configure the event in a<br>
> request context and set the event handler, data and log.<br>
><br>
> I don't really want my timer event handler to do anything -- rather I just<br>
> want the same content phase handler that had previously returned NGX_DONE<br>
> to run again.  In that case, should my timer event handler actually do<br>
> anything at all?  Is there a best practice for this -- i.e. have it point<br>
> to the write_event_handler(), call ngx_http_core_run_phases() or<br>
> ngx_http_run_posted_requests(), etc?<br>
<br>
</div></div>A content phase handler will not be called again (or at least it's<br>
not supposed to).  If a content phase handler returns NGX_DONE, it<br>
means that it's responsible for further request handling, in<br>
particular:<br>
<br>
- you've already done proper request reference counting tweaks<br>
  (normally, by just calling ngx_http_read_client_request_body(),<br>
  which will do r->count++);<br>
<br>
- you are responsible for sending a response and then finalizing<br>
  the request with ngx_http_finalize_request().<br>
<br>
Modules based on the ngx_http_upstream.c (most simple one is<br>
memcached) are examples of content handlers which return NGX_DONE.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Maxim Dounin<br>
<a href="http://nginx.org/" target="_blank">http://nginx.org/</a><br>
<br>
_______________________________________________<br>
nginx-devel mailing list<br>
<a href="mailto:nginx-devel@nginx.org">nginx-devel@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx-devel" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx-devel</a><br>
</font></span></blockquote></div><br></div>