Hi there,
I’m trying to figure out how to implement a non blocking delay between
when a request comes into a module, and when it is responded too.
For example, consider a blocking delay:
static ngx_int_t
ngx_http_my_module_handler(ngx_http_request_t *r)
{
r->headers_out.status = NGX_HTTP_OK
r->header_only = 1;
r->headers_out.content_length_n = 0;
ngx_sleep(10);
rc = ngx_http_send_header(r);
ngx_http_finalize_request(r, rc);
return NGX_DONE;
}
Which would allow a client to connect, wait for 10 seconds, and then
send the response. That’s the behaviour I want, but such a wait as
implemented here is blocking, that is, while the first request is
waiting to be served, all the other requests are blocked until it
completed. I want to make it non blocking so that while one is being
processed (and waiting), others can come into the system and be handled
(which may themselves wait, or may not).
So after some research, I found out about nginx timers, and it seems I
should be able to set a timer/event hander to implement the wait and be
non-blocking:
static void ngx_http_my_module_delay_handler(ngx_event_t *ev);
static ngx_int_t
ngx_http_my_module_handler(ngx_http_request_t *r)
{
r->headers_out.status = NGX_HTTP_OK
r->header_only = 1;
r->headers_out.content_length_n = 0;
ngx_event_t *wakeupFromSleep;
wakeupFromSleep = ngx_pcalloc(r->pool, sizeof(ngx_event_t));
if (wakeupFromSleep == NULL)
ngx_log_stderr(0, “Wakeupfromsleep null”);
wakeupFromSleep->handler = ngx_http_my_module_delay_handler;
wakeupFromSleep->data = r;
ngx_log_stderr(0, “Sleeping for 30 seconds”);
ngx_add_timer(wakeupFromSleep, 30);
return NGX_DONE;
}
static void
ngx_http_my_module_delay_handler(ngx_event_t *ev)
{
int rc;
ngx_http_request_t *r = ev->data;
ngx_log_stderr(0, “Done waiting. Sending response.”);
rc = ngx_http_send_header(r);
ngx_http_finalize_request(r, rc);
ngx_del_timer(ev);
}
Unfortunately, when I connect (say with telnet), and send my request,
the connection immediately closes instead of waiting. In addition, I
never see the “Done waiting. Sending response.” message, indicating to
me that the event isn’t waking up.
My guess as to why the connection is closing immediately has to do with
my returning NGX_DONE in ngx_http_my_module_handler, but I can’t figure
out what else to return that would allow it not to close, and wait for
the timer. I can’t figure out why the timer event isn’t raising, though
I suspect it has to do with the connection immediately returning. I
think it’s just something I’m missing in the setup, but I’m not sure (My
view of how timers should work like this could also be flawed).
Any advice you have would be helpful! Thanks.
Posted at Nginx Forum: