crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs | LICENSE

commit 88d9a9eeabde840bd47b76aa0ede5e6a006a64c3
parent f918d5b94e797ed0459a12f0b146db505ea6cc54
Author: finwo <finwo@pm.me>
Date:   Sat,  3 Jan 2026 19:39:02 +0100

2.76

Diffstat:
MChangeLog | 4++++
MMakefile | 2+-
Mtest/xr-analyze-test | 14++++++++++++--
Mxr/DispatchAlgorithms/algorithm/algorithm | 2+-
Mxr/DispatchAlgorithms/external/external | 2+-
Mxr/DispatchAlgorithms/external/target.cc | 2+-
Mxr/DispatchAlgorithms/firstactive/firstactive | 2+-
Mxr/DispatchAlgorithms/firstactive/target.cc | 2+-
Mxr/DispatchAlgorithms/hashedip/hashedip | 2+-
Mxr/DispatchAlgorithms/hashedip/target.cc | 2+-
Mxr/DispatchAlgorithms/leastconn/leastconn | 2+-
Mxr/DispatchAlgorithms/leastconn/target.cc | 2+-
Mxr/DispatchAlgorithms/roundrobin/roundrobin | 2+-
Mxr/DispatchAlgorithms/roundrobin/target.cc | 32++++++++++++++++++++------------
Mxr/DispatchAlgorithms/storedip/storedip | 2+-
Mxr/DispatchAlgorithms/storedip/target.cc | 2+-
Mxr/DispatchAlgorithms/weightedload/target.cc | 2+-
Mxr/DispatchAlgorithms/weightedload/weightedload | 2+-
Mxr/Dispatchers/tcpdispatcher/handle.cc | 12++++++------
Mxr/balancer/serve.cc | 4+++-
Mxr/sys/main.cc | 24+++++++++++++++++++++---
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();