Reputation: 858
recently i working on a health check script run as php-fpm/nginx and i want to make this script trigger error after a shorter execution time than a regular php script on the same server. something must be wrong if health check took a lot of time for execution.
but i did not figured out why that script ignore execution time limits. eg:
//healthcheck.php
error_reporting(E_ALL);
error_reporting(1);
echo "initial max_execution_time: " . ini_get('max_execution_time') . "\n";
print_r(set_time_limit(2));
echo " - set_time_limit\n";
print_r(ini_set('max_execution_time', 2));
echo " - max_execution_time\n";
echo "altered max_execution_time: " . ini_get('max_execution_time') . "\n";
sleep(4);
print_r(getrusage());
echo 'Current PHP version: ' . phpversion() . "\n";
die('it should not happen');
returns this:
initial max_execution_time: 30
1 - set_time_limit
2 - max_execution_time
altered max_execution_time: 2
Array
(
[ru_oublock] => 0
[ru_inblock] => 0
[ru_msgsnd] => 0
[ru_msgrcv] => 0
[ru_maxrss] => 15032
[ru_ixrss] => 0
[ru_idrss] => 0
[ru_minflt] => 1681
[ru_majflt] => 0
[ru_nsignals] => 0
[ru_nvcsw] => 26
[ru_nivcsw] => 9
[ru_nswap] => 0
[ru_utime.tv_usec] => 5999
[ru_utime.tv_sec] => 0
[ru_stime.tv_usec] => 6998
[ru_stime.tv_sec] => 0
)
Current PHP version: 5.4.35
it should not happen
Upvotes: 2
Views: 1568
Reputation: 46
Here is another alternative:
2) Using declare(), see http://php.net/manual/en/control-structures.declare.php
For example:
define("MAX_EXECUTION_TIME", 10); # seconds
$timeline = time() + MAX_EXECUTION_TIME;
function check_timeout()
{
if( time() < $GLOBALS['timeline'] )
return;
# timeout reached:
echo "<html><html>Sorry, we are very busy, retry later!</body> </html>";
exit;
}
register_tick_function("check_timeout");
declare( ticks=1 ){
# here the process that might require
# so much time; any output generated is
# keep inside a string $s
}
# Ok, process completed, output the result:
echo $s;
From: http://bytes.com/topic/php/answers/620062-how-handle-php-execution-timeouts-gracefully
I don't recommend the usage of $GLOBALS though, I'd pass timeline as an arg of register_tick_function(). http://php.net/manual/en/function.register-tick-function.php
Upvotes: 2
Reputation: 6324
From the PHP documentation:
The maximum execution time is not affected by system calls, stream operations etc.
I'm guessing sleep
uses a system call.
Replacing the sleep
call by some dummy long-running calculation makes the script fail as expected:
<?php
//healthcheck.php
error_reporting(E_ALL);
error_reporting(1);
echo "initial max_execution_time: " . ini_get('max_execution_time') . "\n";
print_r(set_time_limit(2));
echo " - set_time_limit\n";
print_r(ini_set('max_execution_time', 2));
echo " - max_execution_time\n";
echo "altered max_execution_time: " . ini_get('max_execution_time') . "\n";
$dummy = 2;
for($i=0;$i<1000000000;$i++){
$dummy *= 2;
}
print_r(getrusage());
echo 'Current PHP version: ' . phpversion() . "\n";
die('it should not happen');
Output:
PHP Fatal error: Maximum execution time of 2 seconds exceeded in /home/hjusforgues/maxExecutionTime.php on line 14
Upvotes: 2
Reputation: 699
The duration of sleep is ignored by PHP's max execution time.
<?php
set_time_limit(20);
while ($i<=10)
{
echo "i=$i ";
sleep(100);
$i++;
}
?>
Output:
i=0 i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10
Upvotes: 0