Skip to content

Commit eac1609

Browse files
PauliusSapbukka
authored andcommitted
Max spawn child processes rate an once
* Add functionality to expect log config options
1 parent 830d385 commit eac1609

File tree

7 files changed

+100
-4
lines changed

7 files changed

+100
-4
lines changed

sapi/fpm/fpm/fpm_conf.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ static struct ini_value_parser_s ini_fpm_pool_options[] = {
132132
{ "pm.start_servers", &fpm_conf_set_integer, WPO(pm_start_servers) },
133133
{ "pm.min_spare_servers", &fpm_conf_set_integer, WPO(pm_min_spare_servers) },
134134
{ "pm.max_spare_servers", &fpm_conf_set_integer, WPO(pm_max_spare_servers) },
135+
{ "pm.max_spawn_rate", &fpm_conf_set_integer, WPO(pm_max_spawn_rate) },
135136
{ "pm.process_idle_timeout", &fpm_conf_set_time, WPO(pm_process_idle_timeout) },
136137
{ "pm.max_requests", &fpm_conf_set_integer, WPO(pm_max_requests) },
137138
{ "pm.status_path", &fpm_conf_set_string, WPO(pm_status_path) },
@@ -610,6 +611,7 @@ static void *fpm_worker_pool_config_alloc() /* {{{ */
610611

611612
memset(wp->config, 0, sizeof(struct fpm_worker_pool_config_s));
612613
wp->config->listen_backlog = FPM_BACKLOG_DEFAULT;
614+
wp->config->pm_max_spawn_rate = 32; /* 32 by default */
613615
wp->config->pm_process_idle_timeout = 10; /* 10s by default */
614616
wp->config->process_priority = 64; /* 64 means unset */
615617
wp->config->process_dumpable = 0;
@@ -848,7 +850,7 @@ static int fpm_conf_process_all_pools() /* {{{ */
848850
return -1;
849851
}
850852

851-
/* pm.start_servers, pm.min_spare_servers, pm.max_spare_servers */
853+
/* pm.start_servers, pm.min_spare_servers, pm.max_spare_servers, pm.max_spawn_rate */
852854
if (wp->config->pm == PM_STYLE_DYNAMIC) {
853855
struct fpm_worker_pool_config_s *config = wp->config;
854856

@@ -881,6 +883,11 @@ static int fpm_conf_process_all_pools() /* {{{ */
881883
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);
882884
return -1;
883885
}
886+
887+
if (config->pm_max_spawn_rate < 1) {
888+
zlog(ZLOG_ALERT, "[pool %s] pm.max_spawn_rate must be a positive value", wp->config->name);
889+
return -1;
890+
}
884891
} else if (wp->config->pm == PM_STYLE_ONDEMAND) {
885892
struct fpm_worker_pool_config_s *config = wp->config;
886893

@@ -1718,6 +1725,7 @@ static void fpm_conf_dump() /* {{{ */
17181725
zlog(ZLOG_NOTICE, "\tpm.start_servers = %d", wp->config->pm_start_servers);
17191726
zlog(ZLOG_NOTICE, "\tpm.min_spare_servers = %d", wp->config->pm_min_spare_servers);
17201727
zlog(ZLOG_NOTICE, "\tpm.max_spare_servers = %d", wp->config->pm_max_spare_servers);
1728+
zlog(ZLOG_NOTICE, "\tpm.max_spawn_rate = %d", wp->config->pm_max_spawn_rate);
17211729
zlog(ZLOG_NOTICE, "\tpm.process_idle_timeout = %d", wp->config->pm_process_idle_timeout);
17221730
zlog(ZLOG_NOTICE, "\tpm.max_requests = %d", wp->config->pm_max_requests);
17231731
zlog(ZLOG_NOTICE, "\tpm.status_path = %s", STR2STR(wp->config->pm_status_path));

sapi/fpm/fpm/fpm_conf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct fpm_worker_pool_config_s {
7070
int pm_start_servers;
7171
int pm_min_spare_servers;
7272
int pm_max_spare_servers;
73+
int pm_max_spawn_rate;
7374
int pm_process_idle_timeout;
7475
int pm_max_requests;
7576
char *pm_status_path;

sapi/fpm/fpm/fpm_process_ctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
431431
zlog(ZLOG_DEBUG, "[pool %s] %d child(ren) have been created dynamically", wp->config->name, children_to_fork);
432432

433433
/* Double the spawn rate for the next iteration */
434-
if (wp->idle_spawn_rate < FPM_MAX_SPAWN_RATE) {
434+
if (wp->idle_spawn_rate < wp->config->pm_max_spawn_rate) {
435435
wp->idle_spawn_rate *= 2;
436436
}
437437
continue;

sapi/fpm/fpm/fpm_process_ctl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
#include "fpm_events.h"
77

8-
/* spawn max 32 children at once */
9-
#define FPM_MAX_SPAWN_RATE (32)
108
/* 1s (in ms) heartbeat for idle server maintenance */
119
#define FPM_IDLE_SERVER_MAINTENANCE_HEARTBEAT (1000)
1210
/* a minimum of 130ms heartbeat for pctl */
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
FPM: set pm.max_spawn_rate
3+
--SKIPIF--
4+
<?php
5+
include "skipif.inc";
6+
?>
7+
--FILE--
8+
<?php
9+
10+
require_once "tester.inc";
11+
12+
$cfg = <<<EOT
13+
[global]
14+
error_log = {{FILE:LOG}}
15+
log_level = notice
16+
[unconfined]
17+
listen = {{ADDR}}
18+
pm = dynamic
19+
pm.max_children = 5
20+
pm.start_servers = 2
21+
pm.min_spare_servers = 1
22+
pm.max_spare_servers = 3
23+
pm.max_spawn_rate = 64
24+
EOT;
25+
26+
$tester = new FPM\Tester($cfg);
27+
$tester->start(['-t', '-t']);
28+
$tester->expectLogConfigOptions(['pm.max_spawn_rate' => 64]);
29+
$tester->close();
30+
31+
?>
32+
Done
33+
--EXPECT--
34+
Done
35+
--CLEAN--
36+
<?php
37+
require_once "tester.inc";
38+
FPM\Tester::clean();
39+
?>

sapi/fpm/tests/tester.inc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,48 @@ class Tester
13471347
return true;
13481348
}
13491349

1350+
/**
1351+
* Expect log config options
1352+
*
1353+
* @param array $options
1354+
* @return bool
1355+
*/
1356+
public function expectLogConfigOptions(array $options)
1357+
{
1358+
$configOptions = $this->getConfigOptions();
1359+
foreach ($options as $name => $value) {
1360+
if (!isset($configOptions[$name])) {
1361+
return $this->error("Expected config option: {$name} = {$value} but {$name} is not set");
1362+
}
1363+
if ($configOptions[$name] != $value) {
1364+
return $this->error(
1365+
"Expected config option: {$name} = {$value} but got: {$name} = {$configOptions[$name]}"
1366+
);
1367+
}
1368+
}
1369+
1370+
return true;
1371+
}
1372+
1373+
/**
1374+
* Get set config options
1375+
*
1376+
* @return array
1377+
*/
1378+
private function getConfigOptions()
1379+
{
1380+
$options = [];
1381+
1382+
foreach ($this->getLogLines(-1) as $line) {
1383+
preg_match('/.+NOTICE:\s+(.+)\s=\s(.+)/', $line, $matches);
1384+
if ($matches) {
1385+
$options[$matches[1]] = $matches[2];
1386+
}
1387+
}
1388+
1389+
return $options;
1390+
}
1391+
13501392
/**
13511393
* Print content of access log.
13521394
*/

sapi/fpm/www.conf.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ listen = 127.0.0.1:9000
9393
; state (waiting to process). If the number
9494
; of 'idle' processes is greater than this
9595
; number then some children will be killed.
96+
; pm.max_spawn_rate - the maximum number of rate to spawn child
97+
; processes at once.
9698
; ondemand - no children are created at startup. Children will be forked when
9799
; new requests will connect. The following parameter are used:
98100
; pm.max_children - the maximum number of children that
@@ -128,6 +130,12 @@ pm.min_spare_servers = 1
128130
; Note: Mandatory when pm is set to 'dynamic'
129131
pm.max_spare_servers = 3
130132

133+
; The number of rate to spawn child processes at once.
134+
; Note: Used only when pm is set to 'dynamic'
135+
; Note: Mandatory when pm is set to 'dynamic'
136+
; Default Value: 32
137+
;pm.max_spawn_rate = 32
138+
131139
; The number of seconds after which an idle process will be killed.
132140
; Note: Used only when pm is set to 'ondemand'
133141
; Default Value: 10s

0 commit comments

Comments
 (0)