commit 88d9a9eeabde840bd47b76aa0ede5e6a006a64c3
parent f918d5b94e797ed0459a12f0b146db505ea6cc54
Author: finwo <finwo@pm.me>
Date: Sat, 3 Jan 2026 19:39:02 +0100
2.76
Diffstat:
21 files changed, 81 insertions(+), 39 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,7 @@
+2.76 [KK 2011-05-24]
+- Round-robin dispatching takes weights into acocunt. By request of
+ and suggested by David T.
+
2.75 [KK 2011-05-23]
- Signal SIGUSR1 toggles verbose logging, SIGUSR2 toggles debug
logging.
diff --git a/Makefile b/Makefile
@@ -1,7 +1,7 @@
# Top-level Makefile for XR
# -------------------------
-VER ?= 2.75
+VER ?= 2.76
PREFIX ?= $(DESTDIR)/usr
BINDIR ?= $(PREFIX)/sbin
MANDIR ?= $(PREFIX)/share/man
diff --git a/test/xr-analyze-test b/test/xr-analyze-test
@@ -4,12 +4,22 @@ use strict;
my $n = 0;
my $tot = 0;
+my @num;
while (my $line = <STDIN>) {
next unless ($line =~ /^\d/);
$tot += $line;
+ push(@num, $line);
$n++;
}
-exit(1) unless ($n);
+exit(1) if ($n < 2);
+
+my $avg = $tot / $n;
+my $sumsq = 0;
+for my $n (@num) {
+ my $diff = $n - $avg;
+ $sumsq += ($diff * $diff);
+}
print ("Total : $n\n",
- "Average : ", $tot / $n, "\n");
+ "Average : ", $avg, "\n",
+ "SD : ", sqrt($sumsq / ($n - 1)), "\n");
diff --git a/xr/DispatchAlgorithms/algorithm/algorithm b/xr/DispatchAlgorithms/algorithm/algorithm
@@ -9,7 +9,7 @@ class Algorithm: public Thread {
public:
virtual ~Algorithm();
virtual unsigned target(struct in_addr clientip,
- BackendVector const &targetlist) = 0;
+ BackendVector &targetlist) = 0;
};
#endif
diff --git a/xr/DispatchAlgorithms/external/external b/xr/DispatchAlgorithms/external/external
@@ -10,7 +10,7 @@
class External: public Algorithm {
public:
unsigned target(struct in_addr clientip,
- BackendVector const &targetlist);
+ BackendVector &targetlist);
};
#endif
diff --git a/xr/DispatchAlgorithms/external/target.cc b/xr/DispatchAlgorithms/external/target.cc
@@ -1,7 +1,7 @@
#include "external"
unsigned External::target(struct in_addr clientip,
- BackendVector const &targetlist) {
+ BackendVector &targetlist) {
// Prepare command to run
ostringstream o;
diff --git a/xr/DispatchAlgorithms/firstactive/firstactive b/xr/DispatchAlgorithms/firstactive/firstactive
@@ -9,7 +9,7 @@
class Firstactive: public Algorithm {
public:
unsigned target(struct in_addr clientip,
- BackendVector const &targetlist);
+ BackendVector &targetlist);
};
#endif
diff --git a/xr/DispatchAlgorithms/firstactive/target.cc b/xr/DispatchAlgorithms/firstactive/target.cc
@@ -1,7 +1,7 @@
#include "firstactive"
unsigned Firstactive::target(struct in_addr clientip,
- BackendVector const &targetlist) {
+ BackendVector &targetlist) {
if (config.debug()) {
debugmsg("First-active algorithm: " << targetlist.size() <<
" back end(s) to consider\n");
diff --git a/xr/DispatchAlgorithms/hashedip/hashedip b/xr/DispatchAlgorithms/hashedip/hashedip
@@ -11,7 +11,7 @@
class HashedIp: public Algorithm {
public:
unsigned target(struct in_addr clientip,
- BackendVector const &targetlist);
+ BackendVector &targetlist);
};
#endif
diff --git a/xr/DispatchAlgorithms/hashedip/target.cc b/xr/DispatchAlgorithms/hashedip/target.cc
@@ -1,7 +1,7 @@
#include "hashedip"
unsigned HashedIp::target(struct in_addr clientip,
- BackendVector const &targetlist) {
+ BackendVector &targetlist) {
// Nothing to do if we don't have targets.
if (!targetlist.size())
diff --git a/xr/DispatchAlgorithms/leastconn/leastconn b/xr/DispatchAlgorithms/leastconn/leastconn
@@ -10,7 +10,7 @@
class Leastconn: public Algorithm {
public:
unsigned target(struct in_addr clientip,
- BackendVector const &targetlist);
+ BackendVector &targetlist);
};
#endif
diff --git a/xr/DispatchAlgorithms/leastconn/target.cc b/xr/DispatchAlgorithms/leastconn/target.cc
@@ -1,7 +1,7 @@
#include "leastconn"
unsigned Leastconn::target(struct in_addr clientip,
- BackendVector const &targetlist) {
+ BackendVector &targetlist) {
PROFILE("Leastconn::target");
msg("Starting least-connections dispatcher\n");
diff --git a/xr/DispatchAlgorithms/roundrobin/roundrobin b/xr/DispatchAlgorithms/roundrobin/roundrobin
@@ -9,7 +9,7 @@
class Roundrobin: public Algorithm {
public:
unsigned target(struct in_addr clientip,
- BackendVector const &targetlist);
+ BackendVector &targetlist);
};
#endif
diff --git a/xr/DispatchAlgorithms/roundrobin/target.cc b/xr/DispatchAlgorithms/roundrobin/target.cc
@@ -1,18 +1,26 @@
#include "roundrobin"
unsigned Roundrobin::target(struct in_addr clientip,
- BackendVector const &targetlist) {
- // No back ends? Don't even try. One back end? Always that one.
- if (targetlist.size() == 0)
- throw Error("Round robin dispatcher: no backends\n");
-
- if (config.debug())
- for (unsigned i = 0; i < targetlist.size(); i++) {
- unsigned backend_index = targetlist[i];
- debugmsg("Round robin dispatcher: target " << i << " is " <<
- balancer.backend(backend_index).description() << '\n');
- }
-
+ BackendVector &targetlist) {
+ // Regardless of a pre-existent targetlist, we rebuild it here.
+ // We do that to take weights into accounts.
+ static bool building;
+ mutex_lock(&building);
+ targetlist.reset();
+ for (unsigned int i = 0; i < balancer.nbackends(); i++)
+ for (unsigned int j = 0; j < balancer.backend(i).weight(); j++)
+ targetlist.add(i);
+ mutex_unlock(&building);
+
+ if (config.debug()) {
+ ostringstream o;
+ o << "Round robin target list: ";
+ for (unsigned i = 0; i < targetlist.size(); i++)
+ o << targetlist[i] << ' ';
+ o << '\n';
+ debugmsg(o.str());
+ }
+
if (targetlist.size() == 1)
return (targetlist[0]);
diff --git a/xr/DispatchAlgorithms/storedip/storedip b/xr/DispatchAlgorithms/storedip/storedip
@@ -13,7 +13,7 @@
class StoredIp: public Algorithm {
public:
unsigned target(struct in_addr clientip,
- BackendVector const &targetlist);
+ BackendVector &targetlist);
};
#endif
diff --git a/xr/DispatchAlgorithms/storedip/target.cc b/xr/DispatchAlgorithms/storedip/target.cc
@@ -1,7 +1,7 @@
#include "storedip"
unsigned StoredIp::target(struct in_addr clientip,
- BackendVector const &targetlist) {
+ BackendVector &targetlist) {
PROFILE("StoredIP::target");
IPStore::on();
diff --git a/xr/DispatchAlgorithms/weightedload/target.cc b/xr/DispatchAlgorithms/weightedload/target.cc
@@ -1,7 +1,7 @@
#include "weightedload"
unsigned Weightedload::target(struct in_addr clientip,
- BackendVector const &targetlist) {
+ BackendVector &targetlist) {
// First loop thru and add up the weights.
double total_load = 0;
for (unsigned i = 0; i < targetlist.size(); i++) {
diff --git a/xr/DispatchAlgorithms/weightedload/weightedload b/xr/DispatchAlgorithms/weightedload/weightedload
@@ -9,7 +9,7 @@
class Weightedload: public Algorithm {
public:
unsigned target(struct in_addr clientip,
- BackendVector const &targetlist);
+ BackendVector &targetlist);
};
#endif
diff --git a/xr/Dispatchers/tcpdispatcher/handle.cc b/xr/Dispatchers/tcpdispatcher/handle.cc
@@ -6,15 +6,15 @@ void TcpDispatcher::handle() {
clientfd().fd() << " and backend fd " << backendfd().fd() <<
'\n');
+ Fdset readset(maxtimeout(config.client_read_timeout(),
+ config.backend_read_timeout()));
+ readset.add(clientfd());
+ readset.add(backendfd());
while (1) {
- Fdset readset(maxtimeout(config.client_read_timeout(),
- config.backend_read_timeout()));
- readset.add(clientfd());
- readset.add(backendfd());
- readset.wait_r();
-
Socket sock, othersock;
int timeout;
+
+ readset.wait_r();
if (readset.readable(clientfd())) {
sock = clientfd();
othersock = backendfd();
diff --git a/xr/balancer/serve.cc b/xr/balancer/serve.cc
@@ -54,7 +54,9 @@ void Balancer::serve() {
msg("Report requested\n");
reportmsg("*** XR STATUS REPORT STARTS ***\n");
for (unsigned i = 0; i < nbackends(); i++) {
- reportmsg("Back end " << backend(i).description() << '\n');
+ reportmsg("Back end " << i << ": " <<
+ backend(i).description() << ", weight " <<
+ backend(i).weight() << '\n');
reportmsg(" Status: " <<
backend(i).availablestr() << ", " <<
backend(i).livestr() << '\n');
diff --git a/xr/sys/main.cc b/xr/sys/main.cc
@@ -56,10 +56,12 @@ static char **org_argv;
static void sigcatcher (int sig) {
debugmsg("Seen signal " << sig << '\n');
switch (sig) {
+
case SIGHUP:
// Generate a report to the log.
balancer.report(true);
break;
+
case SIGUSR1:
// Toggle verbosity.
if (config.verbose())
@@ -68,15 +70,29 @@ static void sigcatcher (int sig) {
config.verbose(true);
break;
case SIGUSR2:
+
// Toggle debugging.
if (config.debug())
config.debug(false);
else
config.debug(true);
break;
- default:
+
+ case SIGINT:
+ case SIGQUIT:
+ case SIGABRT:
+ case SIGTERM:
+ case SIGSTOP:
+ // Stop the balancer
balancer.terminate(true);
break;
+
+ default:
+ // Ignore
+ ostringstream o;
+ o << "Signal " << sig << " ignored\n";
+ msg(o.str());
+ break;
}
}
@@ -85,7 +101,10 @@ int main (int argc, char **argv) {
PROFILE("main");
static int relevant_sig[] = {
- SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGTERM, SIGSTOP, SIGUSR1, SIGUSR2
+ SIGHUP, // Back end states to log
+ SIGINT, SIGQUIT, SIGABRT, SIGTERM, SIGSTOP, // Terminate
+ SIGUSR1, SIGUSR2, // Toggle verbose/debug
+ SIGPIPE, // Ignore
};
try {
@@ -104,7 +123,6 @@ int main (int argc, char **argv) {
// Load the signal handler.
for (unsigned i = 0; i < sizeof(relevant_sig) / sizeof(int); i++)
signal (relevant_sig[i], sigcatcher);
- signal (SIGPIPE, SIG_IGN);
// Configure the balancer and start serving.
balancer.init();