proxy_conn_rec *conn; /* Single connection for prefork mpm */
};
+/* Keep below in sync with proxy_util.c! */
+
/* worker status bits */
#define PROXY_WORKER_INITIALIZED 0x0001
#define PROXY_WORKER_IGNORE_ERRORS 0x0002
#define PROXY_WORKER_HOT_STANDBY_FLAG 'H'
#define PROXY_WORKER_FREE_FLAG 'F'
+typedef struct wstat {
+ unsigned int bit;
+ char flag;
+ const char *name;
+} wstat;
+
#define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
char sticky[PROXY_BALANCER_MAX_STICKY_SIZE]; /* sticky session identifier */
char nonce[APR_UUID_FORMATTED_LENGTH + 1];
apr_interval_time_t timeout; /* Timeout for waiting on free connection */
- apr_time_t updated; /* timestamp of last update */
+ apr_time_t wupdated; /* timestamp of last change to workers list */
proxy_balancer_method *lbmethod;
int max_attempts; /* Number of attempts before failing */
int index; /* shm array index */
int max_workers; /* maximum number of allowed workers */
const char *name; /* name of the load balancer */
const char *sname; /* filesystem safe balancer name */
- apr_time_t updated; /* timestamp of last update */
+ apr_time_t wupdated; /* timestamp of last change to workers list */
apr_global_mutex_t *mutex; /* global lock for updating lb params */
void *context; /* general purpose storage */
proxy_balancer_shared *s; /* Shared data */
proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
const char *userdata_key = "mod_proxy_balancer_init";
ap_slotmem_instance_t *new = NULL;
+ apr_time_t tstamp;
/* balancer_post_config() will be called twice during startup. So, only
* set up the static data the 1st time through. */
return !OK;
}
-
+ tstamp = apr_time_now();
/*
* Go thru each Vhost and create the shared mem slotmem for
* each balancer's workers
}
balancer->slot = new;
+ /* sync all timestamps */
+ balancer->wupdated = balancer->s->wupdated = tstamp;
+
/* now go thru each worker */
workers = (proxy_worker **)balancer->workers->elts;
for (j = 0; j < balancer->workers->nelts; j++, workers++) {
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, "Cannot share worker");
return !OK;
}
+ worker->s->updated = tstamp;
}
}
s = s->next;
ap_rputs("\n\n<table border='0' style='text-align: left;'><tr>"
"<th>Worker URL</th>"
"<th>Route</th><th>RouteRedir</th>"
- "<th>Factor</th><th>Set</th><th>Status</th>"
+ "<th>Factor</th><th>Set</th><th align='center'>Status</th>"
"<th>Elected</th><th>To</th><th>From</th>"
"</tr>\n", r);
const char *proxy_auth; /* Proxy authorization */
} forward_info;
+/* Keep synced with mod_proxy.h! */
+wstat wstat_tbl[] = {
+ {PROXY_WORKER_INITIALIZED, PROXY_WORKER_INITIALIZED_FLAG, "Init "},
+ {PROXY_WORKER_IGNORE_ERRORS, PROXY_WORKER_IGNORE_ERRORS_FLAG, "Ign "},
+ {PROXY_WORKER_DRAIN, PROXY_WORKER_DRAIN_FLAG, "Drn "},
+ {PROXY_WORKER_IN_SHUTDOWN, PROXY_WORKER_IN_SHUTDOWN_FLAG, "Shut "},
+ {PROXY_WORKER_DISABLED, PROXY_WORKER_DISABLED_FLAG, "Dis "},
+ {PROXY_WORKER_STOPPED, PROXY_WORKER_STOPPED_FLAG, "Stop "},
+ {PROXY_WORKER_IN_ERROR, PROXY_WORKER_IN_ERROR_FLAG, "Err "},
+ {PROXY_WORKER_HOT_STANDBY, PROXY_WORKER_HOT_STANDBY_FLAG, "Stby "},
+ {PROXY_WORKER_FREE, PROXY_WORKER_FREE_FLAG, "Free "},
+ {0x0, '\0', NULL}
+};
+
/* Global balancer counter */
int PROXY_DECLARE_DATA proxy_lb_workers = 0;
static int lb_workers_limit = 0;
memset(bshared, 0, sizeof(proxy_balancer_shared));
bshared->lbmethod = lbmethod;
- bshared->updated = apr_time_now();
bshared->was_malloced = (do_malloc != 0);
/* Retrieve a UUID and store the nonce for the lifetime of
/* recall that we get a ptr to the ptr here */
runtime = apr_array_push(balancer->workers);
*worker = *runtime = apr_palloc(p, sizeof(proxy_worker)); /* right to left baby */
+ /* we've updated the list of workers associated with
+ * this balancer *locally* */
+ balancer->wupdated = apr_time_now();
} else if (conf) {
*worker = apr_array_push(conf->workers);
} else {
PROXY_DECLARE(apr_status_t) ap_proxy_set_wstatus(const char c, int set, proxy_worker *w)
{
unsigned int *status = &w->s->status;
- char bit = toupper(c);
- switch (bit) {
- case PROXY_WORKER_INITIALIZED_FLAG :
- if (set)
- *status |= PROXY_WORKER_INITIALIZED;
- else
- *status &= ~PROXY_WORKER_INITIALIZED;
- break;
- case PROXY_WORKER_IGNORE_ERRORS_FLAG :
- if (set)
- *status |= PROXY_WORKER_IGNORE_ERRORS;
- else
- *status &= ~PROXY_WORKER_IGNORE_ERRORS;
- break;
- case PROXY_WORKER_DRAIN_FLAG :
- if (set)
- *status |= PROXY_WORKER_DRAIN;
- else
- *status &= ~PROXY_WORKER_DRAIN;
- break;
- case PROXY_WORKER_IN_SHUTDOWN_FLAG :
- if (set)
- *status |= PROXY_WORKER_IN_SHUTDOWN;
- else
- *status &= ~PROXY_WORKER_IN_SHUTDOWN;
- break;
- case PROXY_WORKER_DISABLED_FLAG :
- if (set)
- *status |= PROXY_WORKER_DISABLED;
- else
- *status &= ~PROXY_WORKER_DISABLED;
- break;
- case PROXY_WORKER_STOPPED_FLAG :
+ char flag = toupper(c);
+ wstat *pwt = wstat_tbl;
+ while (pwt->bit) {
+ if (flag == pwt->flag) {
if (set)
- *status |= PROXY_WORKER_STOPPED;
+ *status |= pwt->bit;
else
- *status &= ~PROXY_WORKER_STOPPED;
- break;
- case PROXY_WORKER_IN_ERROR_FLAG :
- if (set)
- *status |= PROXY_WORKER_IN_ERROR;
- else
- *status &= ~PROXY_WORKER_IN_ERROR;
- break;
- case PROXY_WORKER_HOT_STANDBY_FLAG :
- if (set)
- *status |= PROXY_WORKER_HOT_STANDBY;
- else
- *status &= ~PROXY_WORKER_HOT_STANDBY;
- break;
- case PROXY_WORKER_FREE_FLAG :
- if (set)
- *status |= PROXY_WORKER_FREE;
- else
- *status &= ~PROXY_WORKER_FREE;
- break;
- default:
- return APR_EINVAL;
- break;
+ *status &= ~(pwt->bit);
+ return APR_SUCCESS;
+ }
+ pwt++;
}
- return APR_SUCCESS;
+ return APR_EINVAL;
}
PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w)
{
- char *ret = NULL;
+ char *ret = "";
unsigned int status = w->s->status;
- if (status & PROXY_WORKER_INITIALIZED)
- ret = apr_pstrcat(p, "Init ", NULL);
- else
- ret = apr_pstrcat(p, "!Init ", NULL);
- if (status & PROXY_WORKER_IGNORE_ERRORS)
- ret = apr_pstrcat(p, ret, "Ign ", NULL);
- if (status & PROXY_WORKER_DRAIN)
- ret = apr_pstrcat(p, ret, "Drn ", NULL);
- if (status & PROXY_WORKER_IN_SHUTDOWN)
- ret = apr_pstrcat(p, ret, "Shut ", NULL);
- if (status & PROXY_WORKER_DISABLED)
- ret = apr_pstrcat(p, ret, "Dis ", NULL);
- if (status & PROXY_WORKER_STOPPED)
- ret = apr_pstrcat(p, ret, "Stop ", NULL);
- if (status & PROXY_WORKER_IN_ERROR)
- ret = apr_pstrcat(p, ret, "Err ", NULL);
- if (status & PROXY_WORKER_HOT_STANDBY)
- ret = apr_pstrcat(p, ret, "Stby ", NULL);
- if (status & PROXY_WORKER_FREE)
- ret = apr_pstrcat(p, ret, "Free ", NULL);
+ wstat *pwt = wstat_tbl;
+ while (pwt->bit) {
+ if (status & pwt->bit)
+ ret = apr_pstrcat(p, ret, pwt->name, NULL);
+ pwt++;
+ }
if (PROXY_WORKER_IS_USABLE(w))
ret = apr_pstrcat(p, ret, "Ok ", NULL);
return ret;