fastcgi – PHP-FPM fastcgi_finish_request reliable?-ThrowExceptions

Exception or error:

After implementing some post-processing in my php script after a fastcgi_finish_request(); statement, I worry about some discrepancies.

Looks like PHP is not executing all the script after fastcgi_finish_request.

In the log files, I can not find a notice regarding this part, no warning, no error or irregularities.

Are there limitations or tips for using fastcgi_finish_request that are not mentioned in the documentation?

How to solve:

Any explicit or implicit output flushing after calling fastcgi_finish_request() will result in exiting the PHP script without any warnings or errors. In other words, calling flush() after fastcgi_finish_request() has been called will behave like you had called exit() instead of flush().

Here’s a PHP ticket that documents the behavior. They’ve labeled it as “not a bug”.

Here’s some code that reproduces the issue:

function writestamp($case, $file){
  file_put_contents($file, "". $case . ": " . time() . "" . PHP_EOL, FILE_APPEND);
}

// Flush buffers and stop output buffering
while (@ob_end_flush());

// Destroy session, otherwise request can't be finished
if(session_status() > 1) session_destroy();

$file = tempnam(sys_get_temp_dir(), 'flushbug_');
echo 'Writing 4 timestamps to: '.$file;

// this one gets called
writestamp('1', $file);

// and this
register_shutdown_function('writestamp', '4', $file);

// finish the request
fastcgi_finish_request();

// as does this
writestamp('2', $file);

// but this one does NOT - calling flush() after fastcgi_finish_request() exits PHP without errors or warnings
flush();
writestamp('3', $file);

A simple fix is to call ignore_user_abort(true) right before or after the fastcgi_finish_request call:

ignore_user_abort(true);
fastcgi_finish_request();

Answer:

So far, for us, almost everything works after calling fastcgi_finish_request(). Except, error_log(). It does not log anything after calling this function.

Answer:

To get errors log working set : catch_workers_output = yes IN your pool conf file www.conf

sed -i "s/;catch_workers_output = yes.*/catch_workers_output = yes/g" /etc/php/<VERSION>/fpm/pool.d/www.conf

Answer:

error_log by default, write logs via fastcgi (thats why you see php log into /var/log/nginx/error.log), when calling fastcgi_finish_request, this will close the link between php-fpm and the fastcgi server (Nginx by instance) hence logs are written no where :/

You can specify log location according documentation at http://php.net/manual/fr/function.error-log.php.

Pay attention that the php worker is still alive, and can saturate the php-fpm pool.

Leave a Reply

Your email address will not be published. Required fields are marked *