]> granicus.if.org Git - apache/commitdiff
Move the shared scoreboard data initization to the balancer module.
authorMladen Turk <mturk@apache.org>
Fri, 10 Sep 2004 08:16:25 +0000 (08:16 +0000)
committerMladen Turk <mturk@apache.org>
Fri, 10 Sep 2004 08:16:25 +0000 (08:16 +0000)
The initialization is done like for the worker, on first request.
This is done because during config phase we don't have a scoreboard
to allocate from. Thanks to Chritian von Roques for spotting that.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@105057 13f79535-47bb-0310-9956-ffa450edef68

modules/proxy/mod_proxy.h
modules/proxy/proxy_balancer.c
modules/proxy/proxy_util.c

index 690cf93e9857895546c84d831446f0e8a11b79f6..17fe6d0bfcc1843ffcdf5a82cfd5aefc39bb180a 100644 (file)
@@ -266,7 +266,6 @@ struct proxy_worker {
 
 /* Runtime worker status informations. Shared in scoreboard */
 typedef struct {
-    int             id;         /* scoreboard id */
     double          lbstatus;   /* Current lbstatus */
     double          lbfactor;   /* dynamic lbfactor */
     apr_size_t      transfered; /* Number of bytes transfered to remote */
@@ -276,12 +275,14 @@ typedef struct {
 
 /* Runtime worker. */
 typedef struct {
-    proxy_balancer     *b;         /* balancer containing this worker */
+    int                id;      /* scoreboard id */
+    proxy_balancer     *b;      /* balancer containing this worker */
     proxy_worker       *w;
     proxy_runtime_stat *s;
 } proxy_runtime_worker;
 
 struct proxy_balancer {
+    int                status;
     apr_array_header_t *workers; /* array of proxy_runtime_workers */
     const char *name;            /* name of the load balancer */
     const char *sticky;          /* sticky session identifier */
index b009016580669dcea1eee51d503ce84dc9c3ee71..a1c6b7eb9137e4d2eb19b930548d09cb99796ce3 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "mod_proxy.h"
 #include "ap_mpm.h"
+#include "scoreboard.h"
 #include "apr_version.h"
 
 module AP_MODULE_DECLARE_DATA proxy_balancer_module;
@@ -31,6 +32,75 @@ module AP_MODULE_DECLARE_DATA proxy_balancer_module;
 #define PROXY_BALANCER_UNLOCK(b)    APR_SUCCESS
 #endif
 
+static int init_runtime_score(apr_pool_t *pool, proxy_balancer *balancer)
+{
+    int i;
+    double median, ffactor = 0.0;
+    proxy_runtime_worker *workers;    
+#if PROXY_HAS_SCOREBOARD
+    lb_score *score;
+    int mpm_daemons;
+#else
+    void *score;
+#endif
+
+    workers = (proxy_runtime_worker *)balancer->workers->elts;
+
+    for (i = 0; i < balancer->workers->nelts; i++) {
+#if PROXY_HAS_SCOREBOARD
+        ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &mpm_daemons);
+        /* Check if we are prefork or single child */
+        if (workers[i].w->hmax && mpm_daemons > 1) {
+            score = ap_get_scoreboard_lb(getpid(), workers[i].id);
+        }
+        else
+#endif
+        {
+            /* Use the plain memory */
+            score = apr_pcalloc(pool, sizeof(proxy_runtime_stat));
+        }
+        workers[i].s = (proxy_runtime_stat *)score;
+    }
+
+    /* Recalculate lbfactors */
+    for (i = 0; i < balancer->workers->nelts; i++) {
+        /* Set to the original configuration */
+        workers[i].s->lbfactor = workers[i].w->lbfactor;
+        ffactor += workers[i].s->lbfactor;
+    }
+    if (ffactor < 100.0) {
+        int z = 0;
+        for (i = 0; i < balancer->workers->nelts; i++) {
+            if (workers[i].s->lbfactor == 0.0) 
+                ++z;
+        }
+        if (z) {
+            median = (100.0 - ffactor) / z;
+            for (i = 0; i < balancer->workers->nelts; i++) {
+                if (workers[i].s->lbfactor == 0.0) 
+                    workers[i].s->lbfactor = median;
+            }
+        }
+        else {
+            median = (100.0 - ffactor) / balancer->workers->nelts;
+            for (i = 0; i < balancer->workers->nelts; i++)
+                workers[i].s->lbfactor += median;
+        }
+    }
+    else if (ffactor > 100.0) {
+        median = (ffactor - 100.0) / balancer->workers->nelts;
+        for (i = 0; i < balancer->workers->nelts; i++) {
+            if (workers[i].s->lbfactor > median)
+                workers[i].s->lbfactor -= median;
+        }
+    } 
+    for (i = 0; i < balancer->workers->nelts; i++) {
+        /* Update the status entires */
+        workers[i].s->lbstatus = workers[i].s->lbfactor;
+    }
+    balancer->status = 1;
+    return 0;
+}
 
 /* Retrieve the parameter with the given name                                */
 static char *get_path_param(apr_pool_t *pool, char *url,
@@ -273,6 +343,10 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
     if (!(*balancer = ap_proxy_get_balancer(r->pool, conf, *url)))
         return DECLINED;
     
+    /* Initialize shared scoreboard data */ 
+    if (!((*balancer)->status))
+        init_runtime_score(conf->pool, *balancer);
+
     /* Step 2: find the session route */
     
     runtime = find_session_route(*balancer, r, &route, url);
@@ -325,8 +399,8 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
         *worker = runtime->w;
     }
     /* Decrease the free channels number */
-    if ((*worker)->cp->nfree)
-        --(*worker)->cp->nfree;
+    /* XXX: This should be the function of apr_reslist */
+    --(*worker)->cp->nfree;
 
     PROXY_BALANCER_UNLOCK(*balancer);
     
@@ -359,8 +433,7 @@ static int proxy_balancer_post_request(proxy_worker *worker,
         return HTTP_INTERNAL_SERVER_ERROR;
     }
     /* increase the free channels number */
-    if (worker->cp->nfree)
-        worker->cp->nfree++;
+    worker->cp->nfree++;
     /* TODO: calculate the bytes transfered */
 
     /* TODO: update the scoreboard status */
@@ -483,6 +556,9 @@ static int balancer_handler(request_rec *r)
     /* First set the params */
     if (bsel) {
         const char *val;
+        if (!bsel->status)
+            init_runtime_score(conf->pool, bsel);
+
         if ((val = apr_table_get(params, "ss"))) {
             if (strlen(val))
                 bsel->sticky = apr_pstrdup(conf->pool, val);
@@ -565,6 +641,9 @@ static int balancer_handler(request_rec *r)
                   ap_get_server_built(), "\n</dt></dl>\n", NULL);
         balancer = (proxy_balancer *)conf->balancers->elts;
         for (i = 0; i < conf->balancers->nelts; i++) {
+            if (!balancer->status)
+                init_runtime_score(conf->pool, balancer);
+
             ap_rputs("<hr />\n<h3>LoadBalancer Status for ", r);
             ap_rvputs(r, "<a href=\"", r->uri, "?b=",
                       balancer->name + sizeof("balancer://") - 1,
index 0a38a56fa6164f9d4a3e29e4f1aaf8fc441f3fb3..2eaeea683e50cb0118187d3b4905cde51278e6df 100644 (file)
@@ -1037,6 +1037,8 @@ PROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer,
 
     ap_str_tolower(uri);
     *balancer = apr_array_push(conf->balancers);
+    memset(*balancer, 0, sizeof(proxy_balancer));
+
     (*balancer)->name = uri;
     (*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_runtime_worker));
     /* XXX Is this a right place to create mutex */
@@ -1150,14 +1152,7 @@ PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker,
 PROXY_DECLARE(void) 
 ap_proxy_add_worker_to_balancer(apr_pool_t *pool, proxy_balancer *balancer, proxy_worker *worker)
 {
-    int i;
-    double median, ffactor = 0.0;
-    proxy_runtime_worker *runtime, *workers;    
-#if PROXY_HAS_SCOREBOARD
-    lb_score *score;
-#else
-    void *score;
-#endif
+    proxy_runtime_worker *runtime;
 
 #if PROXY_HAS_SCOREBOARD
     int mpm_daemons;
@@ -1173,61 +1168,16 @@ ap_proxy_add_worker_to_balancer(apr_pool_t *pool, proxy_balancer *balancer, prox
                           worker->name, balancer->name);
             return;
         }
-        score = ap_get_scoreboard_lb(getpid(), lb_workers);
     }
-    else
 #endif
-    {
-        /* Use the plain memory */
-        score = apr_pcalloc(pool, sizeof(proxy_runtime_stat));
-    }
-    if (!score)
-        return;
     runtime = apr_array_push(balancer->workers);
-    runtime->w = worker;
-    runtime->s = (proxy_runtime_stat *)score;
-    runtime->s->id = lb_workers;
-    /* TODO: deal with the dynamic overflow */
+    runtime->w  = worker;
+    runtime->b  = balancer;
+    runtime->id = lb_workers;
+    runtime->s  = NULL;
+    /* Increase the total runtime count */
     ++lb_workers;
 
-    /* Recalculate lbfactors */
-    workers = (proxy_runtime_worker *)balancer->workers->elts;
-
-    for (i = 0; i < balancer->workers->nelts; i++) {
-        /* Set to the original configuration */
-        workers[i].s->lbfactor = workers[i].w->lbfactor;
-        ffactor += workers[i].s->lbfactor;
-    }
-    if (ffactor < 100.0) {
-        int z = 0;
-        for (i = 0; i < balancer->workers->nelts; i++) {
-            if (workers[i].s->lbfactor == 0.0) 
-                ++z;
-        }
-        if (z) {
-            median = (100.0 - ffactor) / z;
-            for (i = 0; i < balancer->workers->nelts; i++) {
-                if (workers[i].s->lbfactor == 0.0) 
-                    workers[i].s->lbfactor = median;
-            }
-        }
-        else {
-            median = (100.0 - ffactor) / balancer->workers->nelts;
-            for (i = 0; i < balancer->workers->nelts; i++)
-                workers[i].s->lbfactor += median;
-        }
-    }
-    else if (ffactor > 100.0) {
-        median = (ffactor - 100.0) / balancer->workers->nelts;
-        for (i = 0; i < balancer->workers->nelts; i++) {
-            if (workers[i].s->lbfactor > median)
-                workers[i].s->lbfactor -= median;
-        }
-    } 
-    for (i = 0; i < balancer->workers->nelts; i++) {
-        /* Update the status entires */
-        workers[i].s->lbstatus = workers[i].s->lbfactor;
-    }
 }
 
 PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,