[PATCH 4 of 6] Upstream: flush partially filled buffers on upstream timeout

Maxim Dounin mdounin at mdounin.ru
Mon Oct 27 17:53:24 MSK 2008


# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1225109019 -10800
# Node ID aa6cd5a06ccc2037064686bcb183c71d8c65f44a
# Parent  83ba5ad4985f08c8acbffe694fa365a2dff571bf
Upstream: flush partially filled buffers on upstream timeout.

Fix typo in comment while here.

diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -10,7 +10,8 @@
 #include <ngx_event_pipe.h>
 
 
-static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p);
+static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p,
+                                              ngx_int_t do_flush);
 static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p);
 
 static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p);
@@ -40,7 +41,7 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_
 
         p->log->action = "reading upstream";
 
-        if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) {
+        if (ngx_event_pipe_read_upstream(p, 0) == NGX_ABORT) {
             return NGX_ABORT;
         }
 
@@ -88,8 +89,27 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_
 }
 
 
+ngx_int_t
+ngx_event_pipe_flush(ngx_event_pipe_t *p)
+{
+    p->log->action = "reading upstream";
+
+    if (ngx_event_pipe_read_upstream(p, 1) == NGX_ABORT) {
+        return NGX_ABORT;
+    }
+
+    p->log->action = "sending to client";
+
+    if (ngx_event_pipe_write_to_downstream(p) == NGX_ABORT) {
+        return NGX_ABORT;
+    }
+
+    return NGX_OK;
+}
+
+
 static ngx_int_t
-ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
+ngx_event_pipe_read_upstream(ngx_event_pipe_t *p, ngx_int_t do_flush)
 {
     ssize_t       n, size;
     ngx_int_t     rc;
@@ -97,6 +117,9 @@ ngx_event_pipe_read_upstream(ngx_event_p
     ngx_chain_t  *chain, *cl, *ln;
 
     if (p->upstream_eof || p->upstream_error || p->upstream_done) {
+        if (do_flush) {
+            goto flush;
+        }
         return NGX_OK;
     }
 
@@ -330,6 +353,8 @@ ngx_event_pipe_read_upstream(ngx_event_p
             p->free_raw_bufs = cl;
         }
     }
+
+flush:
 
 #if (NGX_DEBUG)
 
@@ -928,7 +953,7 @@ ngx_event_pipe_add_free_buf(ngx_event_pi
         return NGX_OK;
     }
 
-    /* the first free buf is partialy filled, thus add the free buf after it */
+    /* the first free buf is partially filled, thus add the free buf after it */
 
     cl->next = p->free_raw_bufs->next;
     p->free_raw_bufs->next = cl;
diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h
--- a/src/event/ngx_event_pipe.h
+++ b/src/event/ngx_event_pipe.h
@@ -87,6 +87,7 @@ struct ngx_event_pipe_s {
 
 
 ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write);
+ngx_int_t ngx_event_pipe_flush(ngx_event_pipe_t *p);
 ngx_int_t ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf);
 ngx_int_t ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b);
 
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2076,6 +2076,16 @@ ngx_http_upstream_process_body(ngx_event
         } else {
             p->upstream_error = 1;
             ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
+
+            if (ngx_event_pipe_flush(p) == NGX_ABORT) {
+
+                if (downstream->destroyed) {
+                    return;
+                }
+
+                ngx_http_upstream_finalize_request(r, u, 0);
+                return;
+            }
         }
 
     } else {





More information about the nginx mailing list