]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] fix broken redispatch option
authorWilly Tarreau <w@1wt.eu>
Sun, 15 Oct 2006 12:26:02 +0000 (14:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 15 Oct 2006 12:26:02 +0000 (14:26 +0200)
Since the connection queueing was introduced, the "redispatch"
option could not cover the cases where a connection has been
refused by the server after having been marked "in progress".
The fix consists in doing a redispatch in the delayed connection
handling code.

Problem reported by Konrad Rzentarzewski.

src/backend.c
src/proto_http.c

index cda40337ce2f38bd4328dede3efb164f6716d3c4..d0c089178a0638f2133195cbc62d1cc317f61015 100644 (file)
@@ -522,9 +522,6 @@ int srv_retryable_connect(struct session *t)
                }
                /* ensure that we have enough retries left */
                if (srv_count_retry_down(t, conn_err)) {
-                       /* let's try to offer this slot to anybody */
-                       if (may_dequeue_tasks(t->srv, t->proxy))
-                               task_wakeup(&rq, t->srv->queue_mgt);
                        return 1;
                }
        } while (t->srv == NULL || t->conn_retries > 0 || !(t->proxy->options & PR_O_REDISP));
index 51a910a7306c001b4e088d87f520d0c662bff48e..9cd75f323b4eba97e5c7074c13e2911919dddf87 100644 (file)
@@ -1454,6 +1454,30 @@ int process_srv(struct session *t)
                        if (srv_count_retry_down(t, conn_err))
                                return 1;
 
+                       if (t->srv && t->conn_retries == 0 && t->proxy->options & PR_O_REDISP) {
+                               /* We're on our last chance, and the REDISP option was specified.
+                                * We will ignore cookie and force to balance or use the dispatcher.
+                                */
+                               /* let's try to offer this slot to anybody */
+                               if (may_dequeue_tasks(t->srv, t->proxy))
+                                       task_wakeup(&rq, t->srv->queue_mgt);
+
+                               if (t->srv)
+                                       t->srv->failed_conns++;
+                               t->proxy->failed_conns++;
+
+                               t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
+                               t->srv = NULL; /* it's left to the dispatcher to choose a server */
+                               if ((t->flags & SN_CK_MASK) == SN_CK_VALID) {
+                                       t->flags &= ~SN_CK_MASK;
+                                       t->flags |= SN_CK_DOWN;
+                               }
+
+                               /* first, get a connection */
+                               if (srv_redispatch_connect(t))
+                                       return t->srv_state != SV_STIDLE;
+                       }
+
                        do {
                                /* Now we will try to either reconnect to the same server or
                                 * connect to another server. If the connection gets queued