Poundの振り分けアルゴリズムをラウンドロビンに変更してみる

すごい適当なパッチ。
設定ファイルで制御するようにすればマシになるかも。

diff -up Pound-2.3.2.orig/config.c Pound-2.3.2/config.c
--- Pound-2.3.2.orig/config.c	2007-05-18 17:34:53.000000000 +0900
+++ Pound-2.3.2/config.c	2008-02-11 13:40:41.812500000 +0900
@@ -452,6 +452,7 @@ parse_service(FILE *const f_conf, const 
         } else if(!regexec(&End, lin, 4, matches, 0)) {
             for(be = res->backends; be; be = be->next)
                 res->tot_pri += be->priority;
+            res->cur_be = res->backends;
             return res;
         } else if(!regexec(&DynScale, lin, 4, matches, 0)) {
             res->dynscale = atoi(lin + matches[1].rm_so);
diff -up Pound-2.3.2.orig/pound.h Pound-2.3.2/pound.h
--- Pound-2.3.2.orig/pound.h	2007-05-18 17:34:53.000000000 +0900
+++ Pound-2.3.2/pound.h	2008-02-11 13:23:00.046875000 +0900
@@ -330,6 +330,7 @@ typedef struct _service {
     int                 dynscale;   /* true if the back-ends should be dynamically rescaled */
     int                 disabled;   /* true if the service is disabled */
     struct _service     *next;
+    BACKEND             *cur_be;
 }   SERVICE;
 
 #ifndef NO_EXTERNALS
diff -up Pound-2.3.2.orig/svc.c Pound-2.3.2/svc.c
--- Pound-2.3.2.orig/svc.c	2007-05-18 17:34:53.000000000 +0900
+++ Pound-2.3.2/svc.c	2008-02-11 13:43:00.078125000 +0900
@@ -509,6 +509,21 @@ rand_backend(BACKEND *be, int pri)
     return be;
 }
 
+static BACKEND *roundrobin_backend(SERVICE *const svc) {
+  BACKEND *be;
+
+  be = svc->cur_be;
+  svc->cur_be = svc->cur_be->next;
+
+  if (!svc->cur_be) {
+    svc->cur_be = svc->backends;
+  }
+
+  // XXX: for debug
+  printf("be=%p\n", be);
+  return be;
+}
+
 /*
  * Find the right back-end for a request
  */
@@ -529,13 +544,15 @@ get_backend(SERVICE *const svc, const st
     switch(svc->sess_type) {
     case SESS_NONE:
         /* choose one back-end randomly */
-        res = rand_backend(svc->backends, random() % svc->tot_pri);
+        //res = rand_backend(svc->backends, random() % svc->tot_pri);
+        res = roundrobin_backend(svc);
         break;
     case SESS_IP:
         addr2str(key, KEY_SIZE, from_host);
         if((vp = t_find(svc->sessions, key)) == NULL) {
             /* no session yet - create one */
-            res = rand_backend(svc->backends, random() % svc->tot_pri);
+            //res = rand_backend(svc->backends, random() % svc->tot_pri);
+            res = roundrobin_backend(svc);
             svc->sessions = t_add(svc->sessions, key, &res, sizeof(res));
         } else
             memcpy(&res, vp, sizeof(res));
@@ -544,12 +561,14 @@ get_backend(SERVICE *const svc, const st
         if(get_REQUEST(key, svc, request)) {
             if((vp = t_find(svc->sessions, key)) == NULL) {
                 /* no session yet - create one */
-                res = rand_backend(svc->backends, random() % svc->tot_pri);
+                //res = rand_backend(svc->backends, random() % svc->tot_pri);
+                res = roundrobin_backend(svc);
                 svc->sessions = t_add(svc->sessions, key, &res, sizeof(res));
             } else
                 memcpy(&res, vp, sizeof(res));
         } else {
-            res = rand_backend(svc->backends, random() % svc->tot_pri);
+            //res = rand_backend(svc->backends, random() % svc->tot_pri);
+            res = roundrobin_backend(svc);
         }
         break;
     default:
@@ -557,12 +576,14 @@ get_backend(SERVICE *const svc, const st
         if(get_HEADERS(key, svc, headers)) {
             if((vp = t_find(svc->sessions, key)) == NULL) {
                 /* no session yet - create one */
-                res = rand_backend(svc->backends, random() % svc->tot_pri);
+                //res = rand_backend(svc->backends, random() % svc->tot_pri);
+                res = roundrobin_backend(svc);
                 svc->sessions = t_add(svc->sessions, key, &res, sizeof(res));
             } else
                 memcpy(&res, vp, sizeof(res));
         } else {
-            res = rand_backend(svc->backends, random() % svc->tot_pri);
+            //res = rand_backend(svc->backends, random() % svc->tot_pri);
+            res = roundrobin_backend(svc);
         }
         break;
     }