]> granicus.if.org Git - php/commitdiff
Max spawn child processes rate an once
authorPaulius Sapragonas <pauliussap@gmail.com>
Fri, 5 Mar 2021 18:15:30 +0000 (20:15 +0200)
committerJakub Zelenka <bukka@php.net>
Sun, 28 Mar 2021 19:53:58 +0000 (20:53 +0100)
* Add functionality to expect log config options

sapi/fpm/fpm/fpm_conf.c
sapi/fpm/fpm/fpm_conf.h
sapi/fpm/fpm/fpm_process_ctl.c
sapi/fpm/fpm/fpm_process_ctl.h
sapi/fpm/tests/set-pm-max-spawn-rate.phpt [new file with mode: 0644]
sapi/fpm/tests/tester.inc
sapi/fpm/www.conf.in

index 42f75a475df5f0cea4c8612b4539677cf49cd25c..72772031e42d0602d569a26dc305bdc6ccb39506 100644 (file)
@@ -132,6 +132,7 @@ static struct ini_value_parser_s ini_fpm_pool_options[] = {
        { "pm.start_servers",          &fpm_conf_set_integer,     WPO(pm_start_servers) },
        { "pm.min_spare_servers",      &fpm_conf_set_integer,     WPO(pm_min_spare_servers) },
        { "pm.max_spare_servers",      &fpm_conf_set_integer,     WPO(pm_max_spare_servers) },
+       { "pm.max_spawn_rate",         &fpm_conf_set_integer,     WPO(pm_max_spawn_rate) },
        { "pm.process_idle_timeout",   &fpm_conf_set_time,        WPO(pm_process_idle_timeout) },
        { "pm.max_requests",           &fpm_conf_set_integer,     WPO(pm_max_requests) },
        { "pm.status_path",            &fpm_conf_set_string,      WPO(pm_status_path) },
@@ -610,6 +611,7 @@ static void *fpm_worker_pool_config_alloc() /* {{{ */
 
        memset(wp->config, 0, sizeof(struct fpm_worker_pool_config_s));
        wp->config->listen_backlog = FPM_BACKLOG_DEFAULT;
+       wp->config->pm_max_spawn_rate = 32; /* 32 by default */
        wp->config->pm_process_idle_timeout = 10; /* 10s by default */
        wp->config->process_priority = 64; /* 64 means unset */
        wp->config->process_dumpable = 0;
@@ -848,7 +850,7 @@ static int fpm_conf_process_all_pools() /* {{{ */
                        return -1;
                }
 
-               /* pm.start_servers, pm.min_spare_servers, pm.max_spare_servers */
+               /* pm.start_servers, pm.min_spare_servers, pm.max_spare_servers, pm.max_spawn_rate */
                if (wp->config->pm == PM_STYLE_DYNAMIC) {
                        struct fpm_worker_pool_config_s *config = wp->config;
 
@@ -881,6 +883,11 @@ static int fpm_conf_process_all_pools() /* {{{ */
                                zlog(ZLOG_ALERT, "[pool %s] pm.start_servers(%d) must not be less than pm.min_spare_servers(%d) and not greater than pm.max_spare_servers(%d)", wp->config->name, config->pm_start_servers, config->pm_min_spare_servers, config->pm_max_spare_servers);
                                return -1;
                        }
+
+                       if (config->pm_max_spawn_rate < 1) {
+                               zlog(ZLOG_ALERT, "[pool %s] pm.max_spawn_rate must be a positive value", wp->config->name);
+                               return -1;
+                       }
                } else if (wp->config->pm == PM_STYLE_ONDEMAND) {
                        struct fpm_worker_pool_config_s *config = wp->config;
 
@@ -1718,6 +1725,7 @@ static void fpm_conf_dump() /* {{{ */
                zlog(ZLOG_NOTICE, "\tpm.start_servers = %d",           wp->config->pm_start_servers);
                zlog(ZLOG_NOTICE, "\tpm.min_spare_servers = %d",       wp->config->pm_min_spare_servers);
                zlog(ZLOG_NOTICE, "\tpm.max_spare_servers = %d",       wp->config->pm_max_spare_servers);
+               zlog(ZLOG_NOTICE, "\tpm.max_spawn_rate = %d",          wp->config->pm_max_spawn_rate);
                zlog(ZLOG_NOTICE, "\tpm.process_idle_timeout = %d",    wp->config->pm_process_idle_timeout);
                zlog(ZLOG_NOTICE, "\tpm.max_requests = %d",            wp->config->pm_max_requests);
                zlog(ZLOG_NOTICE, "\tpm.status_path = %s",             STR2STR(wp->config->pm_status_path));
index cd71bb53fda66a880eaa728072e13022620f99c0..1d5eabe17c2669669d9b536cdc768dee42bc5c16 100644 (file)
@@ -70,6 +70,7 @@ struct fpm_worker_pool_config_s {
        int pm_start_servers;
        int pm_min_spare_servers;
        int pm_max_spare_servers;
+       int pm_max_spawn_rate;
        int pm_process_idle_timeout;
        int pm_max_requests;
        char *pm_status_path;
index a2f0f935e443cf8ae078c5d1b5f239da5249ed4b..d8c0bc30d1a194cb7a5b08e808566f1cd9980acb 100644 (file)
@@ -431,7 +431,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
                        zlog(ZLOG_DEBUG, "[pool %s] %d child(ren) have been created dynamically", wp->config->name, children_to_fork);
 
                        /* Double the spawn rate for the next iteration */
-                       if (wp->idle_spawn_rate < FPM_MAX_SPAWN_RATE) {
+                       if (wp->idle_spawn_rate < wp->config->pm_max_spawn_rate) {
                                wp->idle_spawn_rate *= 2;
                        }
                        continue;
index f39a489f6177a291de05c7fdd427f1e84770e698..03dc98e931b70d6e94b03440a6c5cc3a21dc1720 100644 (file)
@@ -5,8 +5,6 @@
 
 #include "fpm_events.h"
 
-/* spawn max 32 children at once */
-#define FPM_MAX_SPAWN_RATE (32)
 /* 1s (in ms) heartbeat for idle server maintenance */
 #define FPM_IDLE_SERVER_MAINTENANCE_HEARTBEAT (1000)
 /* a minimum of 130ms heartbeat for pctl */
diff --git a/sapi/fpm/tests/set-pm-max-spawn-rate.phpt b/sapi/fpm/tests/set-pm-max-spawn-rate.phpt
new file mode 100644 (file)
index 0000000..8b5f6b4
--- /dev/null
@@ -0,0 +1,39 @@
+--TEST--
+FPM: set pm.max_spawn_rate
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+
+require_once "tester.inc";
+
+$cfg = <<<EOT
+[global]
+error_log = {{FILE:LOG}}
+log_level = notice
+[unconfined]
+listen = {{ADDR}}
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 2
+pm.min_spare_servers = 1
+pm.max_spare_servers = 3
+pm.max_spawn_rate = 64
+EOT;
+
+$tester = new FPM\Tester($cfg);
+$tester->start(['-t', '-t']);
+$tester->expectLogConfigOptions(['pm.max_spawn_rate' => 64]);
+$tester->close();
+
+?>
+Done
+--EXPECT--
+Done
+--CLEAN--
+<?php
+require_once "tester.inc";
+FPM\Tester::clean();
+?>
index 7aab2d3aa9d11856282d7adcbbd02be86747fb77..9ce4c1a0918a683e1e9bb4d665f522551ad95fcc 100644 (file)
@@ -1347,6 +1347,48 @@ class Tester
         return true;
     }
 
+    /**
+     * Expect log config options
+     *
+     * @param array $options
+     * @return bool
+     */
+    public function expectLogConfigOptions(array $options)
+    {
+        $configOptions = $this->getConfigOptions();
+        foreach ($options as $name => $value) {
+            if (!isset($configOptions[$name])) {
+                return $this->error("Expected config option: {$name} = {$value} but {$name} is not set");
+            }
+            if ($configOptions[$name] != $value) {
+                return $this->error(
+                    "Expected config option: {$name} = {$value} but got: {$name} = {$configOptions[$name]}"
+                );
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Get set config options
+     *
+     * @return array
+     */
+    private function getConfigOptions()
+    {
+        $options = [];
+
+        foreach ($this->getLogLines(-1) as $line) {
+            preg_match('/.+NOTICE:\s+(.+)\s=\s(.+)/', $line, $matches);
+            if ($matches) {
+                $options[$matches[1]] = $matches[2];
+            }
+        }
+
+        return $options;
+    }
+
     /**
      * Print content of access log.
      */
index 3d5658a65d133f72718c5474e035dd2d1c7fc6a2..ebf1bb8c9094c621e765170ce14bc2b07efc1bdf 100644 (file)
@@ -93,6 +93,8 @@ listen = 127.0.0.1:9000
 ;                                    state (waiting to process). If the number
 ;                                    of 'idle' processes is greater than this
 ;                                    number then some children will be killed.
+;             pm.max_spawn_rate    - the maximum number of rate to spawn child
+;                                    processes at once.
 ;  ondemand - no children are created at startup. Children will be forked when
 ;             new requests will connect. The following parameter are used:
 ;             pm.max_children           - the maximum number of children that
@@ -128,6 +130,12 @@ pm.min_spare_servers = 1
 ; Note: Mandatory when pm is set to 'dynamic'
 pm.max_spare_servers = 3
 
+; The number of rate to spawn child processes at once.
+; Note: Used only when pm is set to 'dynamic'
+; Note: Mandatory when pm is set to 'dynamic'
+; Default Value: 32
+;pm.max_spawn_rate = 32
+
 ; The number of seconds after which an idle process will be killed.
 ; Note: Used only when pm is set to 'ondemand'
 ; Default Value: 10s