]> granicus.if.org Git - php/commitdiff
Fix #78413: php-fpm request_terminate_timeout does not take effect after fastcgi_fini...
authorSergei Turchanov <turchanov@farpost.com>
Wed, 28 Aug 2019 04:37:52 +0000 (14:37 +1000)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 30 Sep 2019 10:54:09 +0000 (12:54 +0200)
To retain legacy behavior I decided to add an option to control request
termination logic. If request_terminate_timeout_track_finished is set,
then request will be tracked for time limits even after
fastcgi_finish_request was called.

This patch depends on the fix provided in BUG 78469 (otherwise php-fpm
workers listening on named pipes on Windows will be erroneously terminated)
(PR #4636)

NEWS
UPGRADING
sapi/fpm/fpm/fpm_conf.c
sapi/fpm/fpm/fpm_conf.h
sapi/fpm/fpm/fpm_process_ctl.c
sapi/fpm/fpm/fpm_request.c
sapi/fpm/fpm/fpm_request.h
sapi/fpm/www.conf.in

diff --git a/NEWS b/NEWS
index 7c51dd777fea2343b510a6516800c41168590e5d..d773fd1c64e988484aa7aadfb5d319d3484a6911 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,10 @@ PHP                                                                        NEWS
   . Fixed bug #78442 ('Illegal component' on exif_read_data since PHP7)
        (Kalle)
 
+- FPM:
+  . Fixed bug #78413 (request_terminate_timeout does not take effect after
+    fastcgi_finish_request). (Sergei Turchanov)
+
 - MBString:
   . Fixed bug #78579 (mb_decode_numericentity: args number inconsistency).
     (cmb)
index 4f9c1b5ef2a10e7049dacb135995e29d8f3e9e92..09288192405fc395b3589a25411eebef9d2f60d9 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -273,6 +273,10 @@ FPM:
     disabling output decoration for workers output when catch_workers_output
     enabled.
   . The getallheaders() function is now also available.
+  . In PHP 7.3.11 a new pool option
+    request_terminate_timeout_track_finished has been added. When enabled,
+    request_terminate_timeout will also apply after fastcgi_finish_request()
+    has been called, as well as during execution of shutdown functions.
 
 ========================================
 4. Deprecated Functionality
index 72e6db2e99cf7ef7af68dcc9b3c652bd48a96a81..7a052863091a61ee47c45853a89493407392cc89 100644 (file)
@@ -147,6 +147,7 @@ static struct ini_value_parser_s ini_fpm_pool_options[] = {
        { "request_slowlog_timeout",   &fpm_conf_set_time,        WPO(request_slowlog_timeout) },
        { "request_slowlog_trace_depth", &fpm_conf_set_integer,     WPO(request_slowlog_trace_depth) },
        { "request_terminate_timeout", &fpm_conf_set_time,        WPO(request_terminate_timeout) },
+       { "request_terminate_timeout_track_finished", &fpm_conf_set_boolean, WPO(request_terminate_timeout_track_finished) },
        { "rlimit_files",              &fpm_conf_set_integer,     WPO(rlimit_files) },
        { "rlimit_core",               &fpm_conf_set_rlimit_core, WPO(rlimit_core) },
        { "chroot",                    &fpm_conf_set_string,      WPO(chroot) },
@@ -1674,6 +1675,7 @@ static void fpm_conf_dump() /* {{{ */
                zlog(ZLOG_NOTICE, "\trequest_slowlog_timeout = %ds",   wp->config->request_slowlog_timeout);
                zlog(ZLOG_NOTICE, "\trequest_slowlog_trace_depth = %d", wp->config->request_slowlog_trace_depth);
                zlog(ZLOG_NOTICE, "\trequest_terminate_timeout = %ds", wp->config->request_terminate_timeout);
+               zlog(ZLOG_NOTICE, "\trequest_terminate_timeout_track_finished = %s", BOOL2STR(wp->config->request_terminate_timeout_track_finished));
                zlog(ZLOG_NOTICE, "\trlimit_files = %d",               wp->config->rlimit_files);
                zlog(ZLOG_NOTICE, "\trlimit_core = %d",                wp->config->rlimit_core);
                zlog(ZLOG_NOTICE, "\tchroot = %s",                     STR2STR(wp->config->chroot));
index 44de1f3b032a485777b9457fa96e42b442172fe4..42fa3cca2efebab55ac1a0e49c9fe99e53d648d6 100644 (file)
@@ -81,6 +81,7 @@ struct fpm_worker_pool_config_s {
        int request_slowlog_timeout;
        int request_slowlog_trace_depth;
        int request_terminate_timeout;
+       int request_terminate_timeout_track_finished;
        int rlimit_files;
        int rlimit_core;
        char *chroot;
index 771335551ee397a4a62a8c71c7d6421f25ea139c..17fbe8d3e08762c068ea13b12132658ceb36bcce 100644 (file)
@@ -292,13 +292,14 @@ static void fpm_pctl_check_request_timeout(struct timeval *now) /* {{{ */
        struct fpm_worker_pool_s *wp;
 
        for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
+               int track_finished = wp->config->request_terminate_timeout_track_finished;
                int terminate_timeout = wp->config->request_terminate_timeout;
                int slowlog_timeout = wp->config->request_slowlog_timeout;
                struct fpm_child_s *child;
 
                if (terminate_timeout || slowlog_timeout) {
                        for (child = wp->children; child; child = child->next) {
-                               fpm_request_check_timed_out(child, now, terminate_timeout, slowlog_timeout);
+                               fpm_request_check_timed_out(child, now, terminate_timeout, slowlog_timeout, track_finished);
                        }
                }
        }
index 65f9c4ae441cee84e33fe220a50b60ce5499338a..83401f15539952098dc6d9c9327001a2dd2ba393 100644 (file)
@@ -223,7 +223,7 @@ void fpm_request_finished() /* {{{ */
 }
 /* }}} */
 
-void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *now, int terminate_timeout, int slowlog_timeout) /* {{{ */
+void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *now, int terminate_timeout, int slowlog_timeout, int track_finished) /* {{{ */
 {
        struct fpm_scoreboard_proc_s proc, *proc_p;
 
@@ -245,7 +245,7 @@ void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *now,
        }
 #endif
 
-       if (proc.request_stage > FPM_REQUEST_ACCEPTING && proc.request_stage < FPM_REQUEST_END) {
+       if (proc.request_stage > FPM_REQUEST_ACCEPTING && ((proc.request_stage < FPM_REQUEST_END) || track_finished)) {
                char purified_script_filename[sizeof(proc.script_filename)];
                struct timeval tv;
 
index 782d02dc21c81c91a97cb42a4c0d2af4aaeaec7f..15bce58e4b53f1b00e54366023af873f9e2dae1e 100644 (file)
@@ -13,7 +13,7 @@ void fpm_request_finished();                          /* request processed: cleaning current request *
 struct fpm_child_s;
 struct timeval;
 
-void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *tv, int terminate_timeout, int slowlog_timeout);
+void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *tv, int terminate_timeout, int slowlog_timeout, int track_finished);
 int fpm_request_is_idle(struct fpm_child_s *child);
 const char *fpm_request_get_stage_name(int stage);
 int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv);
index a6227264ea48bbb4f9940fc6d68b3775904546b1..092dec4fff288c4ceca7f8df55d020e97c3cfa0d 100644 (file)
@@ -339,6 +339,14 @@ pm.max_spare_servers = 3
 ; Default Value: 0
 ;request_terminate_timeout = 0
 
+; The timeout set by 'request_terminate_timeout' ini option is not engaged after
+; application calls 'fastcgi_finish_request' or when application has finished and
+; shutdown functions are being called (registered via register_shutdown_function).
+; This option will enable timeout limit to be applied unconditionally
+; even in such cases.
+; Default Value: no
+;request_terminate_timeout_track_finished = no
+
 ; Set open file descriptor rlimit.
 ; Default Value: system defined value
 ;rlimit_files = 1024