1

I gave up trying to debug this issue with Apache-FPM on heroku.

I have a php install script which runs for around 10 minutes. It is expected for the script to take long.

A simple Ajax client-side javascript call makes a POST request to my PHP script, the script runs successfully, and at the end of the script it echos the content back to the client.

jQuery.ajax({
        url: 'longrunningscript.php',
        method: 'POST',
        timeout: 0,
        data: {
            'something': 'something'
        },
        success: function(result) {
            debugger;
            console.log(result);
            
        },
        error: function(jqXHR,textStatus,errorThrown) {
            debugger;
            console.log(textStatus + ' ' + errorThrown);
            
        },
        complete: function(jqXHR,textStatus) {
            console.log(textStatus);
        }
    })

server side config. Note those include the debug settings

My apache server 2.4 is configured with

Timeout 1200
ProxyTimeout 1200
KeepAlive Off
<Directory />
    Options FollowSymlinks
    AllowOverride All
    Require all granted
</Directory>
LogLevel trace6
DirectoryIndex index.php

My php is configured using `.user.ini with

max_execution_time = 0
max_input_time = 0
default_socket_timeout = -1
memory_limit = 256M
display_errors = On
bcmath.scale = 2
short_open_tag = On
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE
post_max_size = 100M
log_errors = On
max_input_vars = 5000
output_buffering = on

php-fpm is configured with

request_terminate_timeout = 0
request_slowlog_timeout = 0
catch_workers_output = true
php_admin_flag[fastcgi.logging] = On
php_admin_flag[file_uploads] = On
php_admin_value[max_file_uploads] = 200
php_admin_value[max_execution_time] = 0
php_admin_value[max_input_time] = 0
php_admin_value[default_socket_timeout] = -1
php_admin_flag[log_errors] = On
php_admin_value[opcache.log_verbosity_level] = 3

longrunningscript.php script is simply

set_time_limit(0);
session_start();
ob_start();
longrunningprocessstarts();
// Unset all of the session variables.
$_SESSION = array();
session_destroy();
session_write_close();
//output

$content = ob_get_contents();

// Erase the buffer in case we want to use it for something else later
if (ob_end_clean()) {
    header("Connection: close");
    header('Content-Encoding: gzip');
    header('Language: en-US');
    header("Content-Length: " . strlen($content));
// All of the data that was in the buffer is now in $content
    http_response_code(200);
    echo $content;
  //  flush();
    fastcgi_finish_request();
}

There is absolutely no timeouts happening on the server side, the server is in LogLevel trace6 and there is no warning, no error, all info just look OK. It logs the /POST request in the log after completing the request successfully and shows logs (retracted)

[http:trace3] [pid 378:tid 140551512872704] http_filters.c(1126): [client x.x.x.x:x] Response sent with status 200, headers:

Date:  app[web.1]: [a time] 
[http:trace5] [pid 378:tid 140551512872704] http_filters.c(1138): [client x.x.x.x:x]   Server: Apache
[http:trace4] [pid 378:tid 140551512872704] http_filters.c(956): [client x.x.x.x:x]   Expires: A date GMT
[http:trace4] [pid 378:tid 140551512872704] http_filters.c(956): [client x.x.x.x:x]    Cache-Control: no-store, no-cache, must-revalidate
[http:trace4] [pid 378:tid 140551512872704] http_filters.c(956): [client x.x.x.x:x]    Pragma: no-cache
[http:trace4] [pid 378:tid 140551512872704] http_filters.c(956): [client x.x.x.x:x]    Connection: close
[http:trace4] [pid 378:tid 140551512872704] http_filters.c(956): [client x.x.x.x:x]    Content-Encoding: gzip
[http:trace4] [pid 378:tid 140551512872704] http_filters.c(956): [client x.x.x.x:x]    Language: en-US
[http:trace4] [pid 378:tid 140551512872704] http_filters.c(956): [client x.x.x.x:x]    
Set-Cookie: PHPSESSID=deleted; expires=Date GMT; Max-Age=0; path=/
[http:trace4] [pid 378:tid 140551512872704] http_filters.c(956): [client x.x.x.x:x]    Content-Length: 1786
[http:trace4] [pid 378:tid 140551512872704] http_filters.c(956): [client x.x.x.x:x]    Content-Type: text/html; charset=UTF-8
[date time] [proxy:debug] [pid 378:tid 140551512872704] proxy_util.c(2453): AH00943: FCGI: has released connection for (heroku-fcgi)

Apache 2.4, PHP 7.4.22

I isolated the issue so much (to the point now using plain Postman POST request)

Where is the issue ?! Is it Apache or FPM / PHP or something wrong I am doing in http request/response is it something else?

My next step would be to troubleshoot the actual http communication itself which I dont know how to do.

please note I am not looking for alternative approaches to address the long-running script like websocket,etc. I want to find out what is the root cause of this issue, and where is the response basically "disappear".

Sam
  • 31
  • 3
  • Does the browser timeout? What does your client say? From what ive found so far chrome for example has max timeout of 5 minutes. – Code Spirit Aug 04 '21 at 09:54
  • @CodeSpirit I don't use Chrome to test anymore- I turned to use Postman (which might also be using the Chrome settings anyway as it is just a browser wrapper). Nevertheless, there is no information in Chrome other than in the Network tab, it shows that the "Request is running". Where is that max timeout in Chrome? This is using an Ajax call and has got a Timeout=0 as above – Sam Aug 04 '21 at 11:13
  • You are getting a client-side timeout. The thing you can do is to feed the browser with some data in between with flush. Check this example: https://stackoverflow.com/questions/3133209/how-to-flush-output-after-each-echo-call – Flash Thunder Aug 29 '21 at 20:11

1 Answers1

0

Indeed chrome internally closes the connection and timeout is after 5 minutes. The optimal solution is to ensure that calls are short and form submits are managed differently.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Sam
  • 31
  • 3