]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] when a server goes up, it now steals part of the proxy's queue.
authorwilly tarreau <willy@wtap.(none)>
Thu, 4 May 2006 13:16:23 +0000 (15:16 +0200)
committerwilly tarreau <willy@wtap.(none)>
Thu, 4 May 2006 13:16:23 +0000 (15:16 +0200)
haproxy.c

index f7b5a8044813896a0a882c27f2191942e0ef40ad..d74ce72eb7522f72bd07e6b4c110829277816082 100644 (file)
--- a/haproxy.c
+++ b/haproxy.c
@@ -1859,36 +1859,38 @@ static inline struct pendconn *pendconn_from_px(struct proxy *px) {
     return LIST_ELEM(px->pendconns.n, struct pendconn *, list);
 }
 
-/* Detaches the next pending connection for either current session's server or
- * current session's proxy, and returns its associated session. If no pending
- * connection is found, NULL is returned. Note that cur->srv cannot be NULL.
+/* Detaches the next pending connection from either a server or a proxy, and
+ * returns its associated session. If no pending connection is found, NULL is
+ * returned. Note that neither <srv> nor <px> can be NULL.
  */
-static struct session *pendconn_get_next_sess(struct session *cur) {
+static struct session *pendconn_get_next_sess(struct server *srv, struct proxy *px) {
     struct pendconn *p;
     struct session *sess;
 
-    p = pendconn_from_srv(cur->srv);
+    p = pendconn_from_srv(srv);
     if (!p) {
-       p = pendconn_from_px(cur->proxy);
+       p = pendconn_from_px(px);
        if (!p)
            return NULL;
-       p->sess->srv = cur->srv;
+       p->sess->srv = srv;
     }
     sess = p->sess;
     pendconn_free(p);
     return sess;
 }
 
-/* Checks if other sessions are waiting for the same server, and wakes the
- * first one up. Note that cur->srv cannot be NULL.
+/* Checks if other sessions are waiting for a known server, and wakes the
+ * first one up. Note that neither <srv> nor <px> can be NULL. Returns 1
+ * if a session has been assigned, 0 if nothing has been done.
  */
-void offer_connection_slot(struct session *cur) {
+static int offer_connection_slot(struct server *srv, struct proxy *px) {
     struct session *sess;
 
-    sess = pendconn_get_next_sess(cur);
+    sess = pendconn_get_next_sess(srv, px);
     if (sess == NULL)
-       return;
+       return 0;
     task_wakeup(&rq, sess->task);
+    return 1;
 }
 
 /* Adds the session <sess> to the pending connection list of server <sess>->srv
@@ -4555,7 +4557,7 @@ int srv_count_retry_down(struct session *t, int conn_err) {
         * we have to pass it on to another session.
         */
        if (t->srv)
-           offer_connection_slot(t);
+           offer_connection_slot(t->srv, t->proxy);
        return 1;
     }
     return 0;
@@ -4589,7 +4591,7 @@ int srv_retryable_connect(struct session *t) {
                               500, t->proxy->errmsg.len500, t->proxy->errmsg.msg500);
            /* release other sessions waiting for this server */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
            return 1;
        }
        /* ensure that we have enough retries left */
@@ -4638,7 +4640,7 @@ int srv_redispatch_connect(struct session *t) {
         */
        /* release other sessions waiting for this server */
        if (t->srv)
-           offer_connection_slot(t);
+           offer_connection_slot(t->srv, t->proxy);
        return 1;
 
     case SRV_STATUS_QUEUED:
@@ -4659,7 +4661,7 @@ int srv_redispatch_connect(struct session *t) {
                           500, t->proxy->errmsg.len500, t->proxy->errmsg.msg500);
        /* release other sessions waiting for this server */
        if (t->srv)
-           offer_connection_slot(t);
+           offer_connection_slot(t->srv, t->proxy);
        return 1;
     }
     /* if we get here, it's because we got SRV_STATUS_OK, which also
@@ -4703,7 +4705,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
            return 1;
        }
        else {
@@ -4871,7 +4873,7 @@ int process_srv(struct session *t) {
                         * we have to pass it on to another session.
                         */
                        if (t->srv)
-                           offer_connection_slot(t);
+                           offer_connection_slot(t->srv, t->proxy);
 
                        return 1;
                    }
@@ -4895,7 +4897,7 @@ int process_srv(struct session *t) {
                     * we have to pass it on to another session.
                     */
                    if (t->srv)
-                       offer_connection_slot(t);
+                       offer_connection_slot(t->srv, t->proxy);
 
                    return 1;
                }
@@ -5334,7 +5336,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
 
            return 1;
        }
@@ -5369,7 +5371,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
 
            return 1;
        }       
@@ -5469,7 +5471,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
 
            return 1;
        }
@@ -5583,7 +5585,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
 
            return 1;
        }
@@ -5599,7 +5601,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
 
            return 1;
        }
@@ -5619,7 +5621,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
 
            return 1;
        }
@@ -5661,7 +5663,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
 
            return 1;
        }
@@ -5677,7 +5679,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
 
            return 1;
        }
@@ -5697,7 +5699,7 @@ int process_srv(struct session *t) {
             * we have to pass it on to another session.
             */
            if (t->srv)
-               offer_connection_slot(t);
+               offer_connection_slot(t->srv, t->proxy);
 
            return 1;
        }
@@ -5842,8 +5844,8 @@ void set_server_down(struct server *s) {
                (s->proxy->srv_bck && !s->proxy->srv_act) ? " Running on backup." : "",
                s->cur_sess, xferred, s->nbpend);
 
-       Warning(trash);
-       send_log(s->proxy, LOG_ALERT, trash);
+       Warning("%s", trash);
+       send_log(s->proxy, LOG_ALERT, "%s", trash);
        
        if (s->proxy->srv_bck == 0 && s->proxy->srv_act == 0) {
            Alert("Proxy %s has no server available !\n", s->proxy->id);
@@ -5976,17 +5978,37 @@ int process_chk(struct task *t) {
                s->state |= SRV_RUNNING;
 
                if (s->health == s->rise) {
+                   int xferred;
+
                     recount_servers(s->proxy);
                    recalc_server_map(s->proxy);
-                   Warning("%sServer %s/%s UP. %d active and %d backup servers online.%s\n",
-                            s->state & SRV_BACKUP ? "Backup " : "",
-                            s->proxy->id, s->id, s->proxy->srv_act, s->proxy->srv_bck,
-                            (s->proxy->srv_bck && !s->proxy->srv_act) ? " Running on backup." : "");
-                   send_log(s->proxy, LOG_NOTICE,
-                             "%sServer %s/%s is UP. %d active and %d backup servers online.%s\n",
-                             s->state & SRV_BACKUP ? "Backup " : "",
-                             s->proxy->id, s->id, s->proxy->srv_act, s->proxy->srv_bck,
-                             (s->proxy->srv_bck && !s->proxy->srv_act) ? " Running on backup." : "");
+
+                   /* check if we can handle some connections queued at the proxy. We
+                    * will take as many as we can handle.
+                    */
+                   for (xferred = 0; !s->maxconn || xferred < s->maxconn; xferred++) {
+                       struct session *sess;
+                       struct pendconn *p;
+
+                       p = pendconn_from_px(s->proxy);
+                       if (!p)
+                           break;
+                       p->sess->srv = s;
+                       sess = p->sess;
+                       pendconn_free(p);
+                       task_wakeup(&rq, sess->task);
+                   }
+
+                   sprintf(trash,
+                           "%sServer %s/%s is UP. %d active and %d backup servers online.%s"
+                           " %d sessions requeued, %d total in queue.\n",
+                           s->state & SRV_BACKUP ? "Backup " : "",
+                           s->proxy->id, s->id, s->proxy->srv_act, s->proxy->srv_bck,
+                           (s->proxy->srv_bck && !s->proxy->srv_act) ? " Running on backup." : "",
+                           xferred, s->nbpend);
+
+                   Warning("%s", trash);
+                   send_log(s->proxy, LOG_NOTICE, "%s", trash);
                }
 
                s->health = s->rise + s->fall - 1; /* OK now */