--- pen.c.orig 2006-06-24 11:11:48.000000000 +0200
+++ pen.c 2007-09-10 13:38:20.000000000 +0200
@@ -102,6 +104,7 @@
struct in_addr addr;
int c; /* connections */
int weight; /* default 1 */
+ int priority; /* default 1 (higher is better) */
int maxc; /* max connections, soft limit */
int hard; /* max connections, hard limit */
unsigned long long sx, rx; /* bytes sent, received */
@@ -148,6 +151,7 @@
static int tracking_time = TRACKING_TIME;
static int roundrobin = 0;
static int weight = 0;
+static int priority = 0;
static int hash = 0;
static int stubborn = 0;
static int nblock = 1;
@@ -496,6 +500,7 @@
"
sent | \n"
"received | \n"
"weight | \n"
+ "priority | \n"
"\n");
for (i = 0; i < nservers; i++) {
fprintf(fp,
@@ -515,7 +520,8 @@
servers[i].status, servers[i].port,
servers[i].c, servers[i].maxc, servers[i].hard,
servers[i].sx, servers[i].rx,
- servers[i].weight);
+ servers[i].weight,
+ servers[i].priority);
}
fprintf(fp, "\n");
@@ -666,6 +672,11 @@
unsigned long ad = cli.s_addr;
time_t now = time(NULL);
+ if (debuglevel>1) debug("Looking up client %s", inet_ntoa(cli));
+ if (http) {
+ if (debuglevel>1) debug("Looking up client %s", inet_ntoa(cli));
+ }
+
for (i = 0; i < clients_max; i++) {
if (clients[i].addr.s_addr == ad) break;
}
@@ -1120,6 +1131,7 @@
" -H add X-Forwarded-For header in http requests\n"
" -P use poll() rather than select()\n"
" -W use weight for server selection\n"
+ " -I use priority for server selection\n"
" -X enable 'exit' command for control port\n"
" -a debugging dumps in ascii format\n"
" -b sec blacklist time in seconds [%d]\n"
@@ -1586,6 +1598,8 @@
webfile = NULL;
} else if (!strcmp(p, "weight")) {
weight = 0;
+ } else if (!strcmp(p, "priority")) {
+ priority = 0;
}
} else if (!strcmp(p, "pid")) {
sprintf(b, "%ld\n", (long)getpid());
@@ -1625,6 +1639,8 @@
servers[n].status = time(NULL)+atoi(q)-blacklist_time;
} else if (!strcmp(p, "weight")) {
servers[n].weight = atoi(q);
+ } else if (!strcmp(p, "priority")) {
+ servers[n].priority = atoi(q);
}
}
} else if (!strcmp(p, "servers")) {
@@ -1670,6 +1686,8 @@
}
} else if (!strcmp(p, "weight")) {
weight = 1;
+ } else if (!strcmp(p, "priority")) {
+ priority = 1;
} else if (!strcmp(p, "write")) {
p = strtok(NULL, " ");
if (!p) p = cfgfile;
@@ -1734,14 +1752,32 @@
{
int best_server = -1;
int best_load = -1;
- int i, load;
+ int best_priority_value = -1;
+ int i, load, priority_value;
int now = (int)time(NULL);
if (debuglevel) debug("server_by_weight()");
+ if (priority) {
+ for (i = 0; i < nservers; i++) {
+ if (now-servers[i].status < blacklist_time || servers[i].weight == 0) {
+ continue;
+ }
+ priority_value = servers[i].priority;
+ if (priority_value > best_priority_value) {
+ if (debuglevel)
+ debug("Server %d has priority %d",
+ i, priority_value);
+ best_priority_value = priority_value;
+ }
+ }
+ }
for (i = 0; i < nservers; i++) {
if (now-servers[i].status < blacklist_time || servers[i].weight == 0) {
continue;
}
+ if ((priority) && servers[i].priority < best_priority_value) {
+ continue;
+ }
load = servers[i].c/servers[i].weight;
if (best_server == -1 || load < best_load) {
if (debuglevel)
@@ -1755,6 +1791,45 @@
return best_server;
}
+static int server_by_priority(void)
+{
+ int best_server = -1;
+ int best_load = -1;
+ int best_priority_value = -1;
+ int i, load, priority_value;
+ int now = (int)time(NULL);
+
+ if (debuglevel) debug("server_by_priority()");
+ for (i = 0; i < nservers; i++) {
+ if (now-servers[i].status < blacklist_time) {
+ continue;
+ }
+ priority_value = servers[i].priority;
+ if (priority_value > best_priority_value) {
+ if (debuglevel)
+ debug("Server %d has priority %d",
+ i, priority_value);
+ best_priority_value = priority_value;
+ }
+ }
+ for (i = 0; i < nservers; i++) {
+ if (now-servers[i].status < blacklist_time || servers[i].priority < best_priority_value) {
+ continue;
+ }
+ load = servers[i].c;
+ if (best_server == -1 || load < best_load) {
+ if (debuglevel)
+ debug("Server %d has load %d",
+ i, load);
+ best_load = load;
+ best_server = i;
+ }
+ }
+
+ if (debuglevel) debug("Least loaded server with highest priority = %d", best_server);
+ return best_server;
+}
+
static void add_client(int downfd, struct sockaddr_in *cli_addr)
{
int upfd = -1, clino = -1, index = -1, n, pd;
@@ -1806,6 +1881,13 @@
if (upfd != -1) goto Success;
}
}
+ if (priority) {
+ index = server_by_priority();
+ if (index != -1) {
+ upfd = try_server(index, 0, cli);
+ if (upfd != -1) goto Success;
+ }
+ }
if (hash) {
index = cli % nservers;
upfd = try_server(index, 0, cli);
@@ -2489,9 +2571,9 @@
char b[1024];
#ifdef HAVE_SSL
- char *opt = "B:C:F:S:T:b:c:e:j:l:o:p:t:u:w:x:DHPQWXadfhnrsE:K:G:A:ZRL:";
+ char *opt = "B:C:F:S:T:b:c:e:j:l:o:p:t:u:w:x:DHPQWIXadfhnrsE:K:G:A:ZRL:";
#else
- char *opt = "B:C:F:S:T:b:c:e:j:l:o:p:t:u:w:x:DHPQWXadfhnrs";
+ char *opt = "B:C:F:S:T:b:c:e:j:l:o:p:t:u:w:x:DHPQWIXadfhnrs";
#endif
while ((c = getopt(argc, argv, opt)) != -1) {
@@ -2526,6 +2608,9 @@
case 'W':
weight = 1;
break;
+ case 'I':
+ priority = 1;
+ break;
case 'X':
exit_enabled = 1;
break;