From 80d6d4df9de73b4a6b6e8c92227e24f80937be3b Mon Sep 17 00:00:00 2001 From: Camden Narzt Date: Mon, 20 Jan 2025 10:25:19 -0700 Subject: [PATCH] env var based routing selection --- src/agent/Core/ApplicationPool/Group.h | 4 ++ .../Group/ProcessListManagement.cpp | 67 +++++++++++++++++++ .../Group/SessionManagement.cpp | 32 +++++++-- 3 files changed, 98 insertions(+), 5 deletions(-) diff --git a/src/agent/Core/ApplicationPool/Group.h b/src/agent/Core/ApplicationPool/Group.h index 34b556782f..d9cdf8ec0a 100644 --- a/src/agent/Core/ApplicationPool/Group.h +++ b/src/agent/Core/ApplicationPool/Group.h @@ -233,9 +233,13 @@ class Group: public boost::enable_shared_from_this { /****** Process list management ******/ Process *findProcessWithStickySessionId(unsigned int id) const; + Process *findProcessWithStickySessionIdOrLowestBusyness(unsigned int id) const; + Process *findProcessWithLowestBusyness(const ProcessList &processes) const; + Process *findEnabledProcessWithLowestBusyness() const; Process *findBestProcessPreferringStickySessionId(unsigned int id) const; Process *findBestProcess(const ProcessList &processes) const; Process *findBestEnabledProcess() const; + bool useNewRouting() const; void addProcessToList(const ProcessPtr &process, ProcessList &destination); void removeProcessFromList(const ProcessPtr &process, ProcessList &source); diff --git a/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp b/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp index fdded156a1..21ac00fa94 100644 --- a/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp +++ b/src/agent/Core/ApplicationPool/Group/ProcessListManagement.cpp @@ -63,6 +63,73 @@ Group::findProcessWithStickySessionId(unsigned int id) const { return NULL; } +Process * +Group::findProcessWithStickySessionIdOrLowestBusyness(unsigned int id) const { + int leastBusyProcessIndex = -1; + int lowestBusyness = 0; + unsigned int i, size = enabledProcessBusynessLevels.size(); + const int *enabledProcessBusynessLevels = &this->enabledProcessBusynessLevels[0]; + for (i = 0; i < size; i++) { + Process *process = enabledProcesses[i].get(); + if (process->getStickySessionId() == id) { + return process; + } else if (leastBusyProcessIndex == -1 || enabledProcessBusynessLevels[i] < lowestBusyness) { + leastBusyProcessIndex = i; + lowestBusyness = enabledProcessBusynessLevels[i]; + } + } + + if (leastBusyProcessIndex == -1) { + return NULL; + } else { + return enabledProcesses[leastBusyProcessIndex].get(); + } +} + +Process * +Group::findProcessWithLowestBusyness(const ProcessList &processes) const { + if (processes.empty()) { + return NULL; + } + + int lowestBusyness = -1; + Process *leastBusyProcess = NULL; + ProcessList::const_iterator it; + ProcessList::const_iterator end = processes.end(); + for (it = processes.begin(); it != end; it++) { + Process *process = (*it).get(); + int busyness = process->busyness(); + if (lowestBusyness == -1 || lowestBusyness > busyness) { + lowestBusyness = busyness; + leastBusyProcess = process; + } + } + return leastBusyProcess; +} + +/** + * Cache-optimized version of findProcessWithLowestBusyness() for the common case. + */ +Process * +Group::findEnabledProcessWithLowestBusyness() const { + if (enabledProcesses.empty()) { + return NULL; + } + + int leastBusyProcessIndex = -1; + int lowestBusyness = 0; + unsigned int i, size = enabledProcessBusynessLevels.size(); + const int *enabledProcessBusynessLevels = &this->enabledProcessBusynessLevels[0]; + + for (i = 0; i < size; i++) { + if (leastBusyProcessIndex == -1 || enabledProcessBusynessLevels[i] < lowestBusyness) { + leastBusyProcessIndex = i; + lowestBusyness = enabledProcessBusynessLevels[i]; + } + } + return enabledProcesses[leastBusyProcessIndex].get(); +} + /** * Return the process with the given sticky session ID if it exists. * If not, then find the "best" enabled process to route a request to, diff --git a/src/agent/Core/ApplicationPool/Group/SessionManagement.cpp b/src/agent/Core/ApplicationPool/Group/SessionManagement.cpp index 41dd73e874..3aef2a7525 100644 --- a/src/agent/Core/ApplicationPool/Group/SessionManagement.cpp +++ b/src/agent/Core/ApplicationPool/Group/SessionManagement.cpp @@ -29,6 +29,7 @@ #ifdef INTELLISENSE #include #endif +#include #include #include @@ -63,9 +64,14 @@ using namespace boost; */ Group::RouteResult Group::route(const Options &options) const { + Process *process = nullptr; if (OXT_LIKELY(enabledCount > 0)) { if (options.stickySessionId == 0) { - Process *process = findBestProcess(enabledProcesses); + if (OXT_LIKELY(useNewRouting())) { + process = findBestProcess(enabledProcesses); + } else { + process = findEnabledProcessWithLowestBusyness(); + } if (process != nullptr) { assert(process->canBeRoutedTo()); return RouteResult(process); @@ -73,8 +79,11 @@ Group::route(const Options &options) const { return RouteResult(NULL, true); } } else { - Process *process = findBestProcessPreferringStickySessionId( - options.stickySessionId); + if (OXT_LIKELY(useNewRouting())) { + process = findBestProcessPreferringStickySessionId(options.stickySessionId); + }else{ + process = findProcessWithStickySessionIdOrLowestBusyness(options.stickySessionId); + } if (process != nullptr) { if (process->canBeRoutedTo()) { return RouteResult(process); @@ -86,7 +95,11 @@ Group::route(const Options &options) const { } } } else { - Process *process = findBestProcess(disablingProcesses); + if (OXT_LIKELY(useNewRouting())) { + process = findBestProcess(disablingProcesses); + } else { + process = findProcessWithLowestBusyness(disablingProcesses); + } if (process != nullptr) { assert(process->canBeRoutedTo()); return RouteResult(process); @@ -313,7 +326,12 @@ Group::get(const Options &newOptions, const GetCallback &callback, assert(m_spawning || restarting() || poolAtFullCapacity()); if (disablingCount > 0 && !restarting()) { - Process *process = findBestProcess(disablingProcesses); + Process *process = nullptr; + if (OXT_LIKELY(useNewRouting())) { + process = findBestProcess(disablingProcesses); + } else { + process = findProcessWithLowestBusyness(disablingProcesses); + } if (process != nullptr && !process->isTotallyBusy()) { return newSession(process, newOptions.currentTime); } @@ -341,6 +359,10 @@ Group::get(const Options &newOptions, const GetCallback &callback, } } +bool +Group::useNewRouting() const { + return !Agent::Fundamentals::getEnvBool("PASSENGER_OLD_ROUTING", false); +} } // namespace ApplicationPool2 } // namespace Passenger