amazon web services - Impose time limit to popen/fgets in PHP
I want impose a time limit to a process reading using fgets opened by popen in PHP.
I have the next code:
$handle = popen("tail -F -n 30 /tmp/pushlog.txt 2>&1", "r");
while(!feof($handle)) {
$buffer = fgets($handle);
echo "data: ".$buffer."\n";
@ob_flush();
flush();
}
pclose($handle);
I tried without success:
set_time_limit(60);
ignore_user_abort(false);
The process is as follow:
- The browser send a GET request waiting for a Answer in HTML5 Server side events format.
- The request is received by AWS Load Balancer and is forwarded to EC2 instances.
- The answer is the last 30 lines of the file
- The browser receive it in 30 messages and the connection is persisted.
- If tail command sends a new line it is returned else fgets wait undefined time until new line is returned from tail command.
- AWS Load Balancer after 60 seconds of network inactivity (No new lines in 60 seconds) closes the connection to the browser. The connection to EC2 instance is not closed.
- The browser detect that the connection is closed and it opens a new connection, the process go back to step 1.
AS this steps describe, the connection between AWS Load Balancer and EC2 instance is never closed, after a few hours/days there is hundreds and hundreds of tail and httpd process running and the server start not answering.
Of course it appear to be a AWS Load Balancer bug, but I don't want start a process to gain the attention from Amazon and wait for a fix.
My temporary solution is do a sudo kill tail to kill the process before the server becomes unstable.
I think PHP doesn't stop the script because PHP is "blocked" waiting for fgets to finish.
I know that the time limit of AWS Load Balancer is editable, but I want keep in the default value, even a higher limit is not going to fix the problem.
I don't know if I need change the question to How to execute a process in linux with a time limit / timeout?.
PHP 5.5.22 / Apache 2.4 / Linux Kernel 3.14.35-28.38.amzn1.x86_64
Answer
Solution:
Tested with PHP 5.5.20:
Answer
Solution:
Rather than using a process file pointer, I went with my "multitasking" approach. I use this code to spawn other "processes" Kind of a multitasking cheat.
I call a Script, hang.php, that just hangs for 90 seconds:
sleep(90)
.You may want to adjust the stream and stream_select timeouts.
Create stream(s)
Additional scripts can be run by adding the stream:
$sockets[$id++] = $stream;
Below will put anything read in to the
$result[$id]
array.Monitor the streams:
.
When I want to kill a process I use
system('ps auxww')
to get the pid and kill it withsystem("kill $pid")
kill.php