summaryrefslogtreecommitdiffstats
path: root/server/mpm/event/event.c
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2021-10-15 12:29:00 +0200
committerYann Ylavic <ylavic@apache.org>2021-10-15 12:29:00 +0200
commit4f9e7cf5d7dda9011afee1b886f5c27eec77d148 (patch)
tree6b13a380a52f6cc3006030909624654e38fec650 /server/mpm/event/event.c
parent * mod_http2: hopeful (as always) fix for the stalling in 400_20. (diff)
downloadapache2-4f9e7cf5d7dda9011afee1b886f5c27eec77d148.tar.xz
apache2-4f9e7cf5d7dda9011afee1b886f5c27eec77d148.zip
mpm_event: Restart stopping of idle children after a load peak. PR 65626.
r1770752 added an heuristic to avoid stopping children when the load triggers MaxSpareThreads but children take some time to shut down until the point where active_daemons_limit/ServerLimit is reached (scoreboard full) and no child gets created to handle incoming connections. However when this happens there is nothing to stop children again when the load settles down (besides MaxRequestsPerChild, which may be 0) so let's restart to stop children again if/when idle_thread_count reaches max_workers / 4. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1894285 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r--server/mpm/event/event.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
index aa6304042a..2e7bb6bfdb 100644
--- a/server/mpm/event/event.c
+++ b/server/mpm/event/event.c
@@ -3187,7 +3187,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
* gracefully finishing processes may accumulate, filling up the
* scoreboard. To avoid running out of scoreboard entries, we
* don't shut down more processes when the total number of processes
- * is high.
+ * is high, until there are more than max_workers/4 idle threads.
*
* XXX It would be nice if we could
* XXX - kill processes without keepalive connections first
@@ -3195,13 +3195,19 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
* XXX depending on server load, later be able to resurrect them
* or kill them
*/
- if (retained->total_daemons <= active_daemons_limit &&
- retained->total_daemons < server_limit) {
+ if ((retained->total_daemons <= active_daemons_limit
+ && retained->total_daemons < server_limit)
+ /* The above test won't transition from true to false until a child
+ * exits by itself (i.e. MaxRequestsPerChild reached), so the below
+ * test makes sure that the situation unblocks when the load falls
+ * significantly (regardless of MaxRequestsPerChild, e.g. 0) */
+ || idle_thread_count > max_workers/4 / num_buckets) {
/* Kill off one child */
ap_mpm_podx_signal(retained->buckets[child_bucket].pod,
AP_MPM_PODX_GRACEFUL);
retained->idle_spawn_rate[child_bucket] = 1;
} else {
+ /* Still busy enough, don't kill */
ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf,
"Not shutting down child: total daemons %d / "
"active limit %d / ServerLimit %d",