Hi Brian,
> I have created a (very) small module that demonstrates the problem.
> It can be downloaded here:
>
> http://www.mediafire.com/?yij1tmyjzyz
Few notes:
1) This problem isn't related to caching at all, simple "proxy_pass"
also produces this behavior.
2) I believe that execv() is source of this problem, not fork().
Anyway, it seems that calling execv() with open sockets copies all file
descriptors to new process and nginx is expecting some action to happen
on them. Since there is no action, nginx waits until your process exits
(and OS closes all its file descriptors for you).
I've attached simple patch, which fixes this problem.
There are few things to consider:
1) This works well with kevent (*BSD), I'm not sure what will be the
effect of closing sockets registered with epoll (Linux), because when I
was developing ngx_slowfs_cache, nginx crashed when listening sockets
were closed after fork() under Linux.
2) This works as expected for single request. Under high load you might
need to close sockets for *all* requests... But I'm not really sure
about this and it's up to you to test this.
Best regards,
Piotr Sikora < piotr.sikora@frickle.com >
--- ngx_http_bogus_module.c.orig Tue Dec 22 14:18:43 2009
+++ ngx_http_bogus_module.c Tue Dec 22 14:18:21 2009
@@ -10,7 +10,7 @@
static char *ngx_http_bogus_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static void *ngx_http_bogus_create_loc_conf(ngx_conf_t *cf);
-void ngx_http_bogus_launch_child();
+void ngx_http_bogus_launch_child(ngx_http_request_t *r);
static ngx_command_t ngx_http_bogus_commands[] = {
@@ -56,7 +56,7 @@
};
void
-ngx_http_bogus_launch_child()
+ngx_http_bogus_launch_child(ngx_http_request_t *r)
{
char *argv[] = {"bogochild", NULL};
pid_t child = 0;
@@ -67,6 +67,7 @@
if (stat(child_path, &statbuf)==-1) return;
if ((child = fork())==0) {
+ ngx_close_connection(r->connection);
execv(child_path, argv);
} else {
/* wait for child to be ready, signaled by dead parent */
@@ -90,7 +91,7 @@
log = r->connection->log;
ngx_log_error(NGX_LOG_INFO, log, 0, "entering bogus_request_body_handler");
- ngx_http_bogus_launch_child();
+ ngx_http_bogus_launch_child(r);
output = (u_char *) strdup("Success");
len = ngx_strlen(output);
b = ngx_create_temp_buf(r->pool, len + 1);
_______________________________________________
nginx mailing list
nginx@nginx.org
http://nginx.org/mailman/listinfo/nginx