Reputation: 1518
I am running a website where we are serving a large amount of files from a folder mounted over Fuse (cloudfuse - a Rackspace Cloudfiles container), it works wonderfully most of the time however every now and again the Fuse connection stalls and all my Apache processes hang waiting for a file_exists() function to return.
My question, is there anyway to set a timeout for a specific function or to use another function to check if the file exists but return with false if function takes longer than x seconds?
Upvotes: 5
Views: 2656
Reputation: 1103
Similar to Peters answer, I used that to figure out something simple/elegant (this probably won't work 1:1 on windows though):
$command = "timeout 10 ls '{$file}'";
exec($command, $output, $exit_code);
if($exit_code !== 0) {
// non 0 exit code means it failed.
// Exit code will be 124 if the ls command timed out
// (didn't return after 10 seconds in this case)
echo "Failed to check if file exists, ls command exited with code '{$exit_code}': `{$command}` Output: ".implode("\n", $output));
// do error handling...
}
See linux man page for timeout command for more info. The exit code will be 124 when it times out: "If the command times out, and --preserve-status is not set, then exit with status 124."
If the file exists and is readable (user running this has permissions to see the file) then the exit code will be 0. Otherwise it will likely be 2, as demonstrated below (run from linux)
# ls not_a_file
ls: cannot access not_a_file: No such file or directory
# echo "exit code for last command was $?"
exit code for last command was 2
This also works on stale NFS mounts, which was my problem, when using file_exists or just ls on that when mount is hung results in an "infinite" time to return.
Upvotes: 0
Reputation: 16943
I think file_exists()
is only simple function, and is not intended for such operations.
Workaround #1 (quite elegant)
Workaround #2 (simpler, not elegant at all)
Upvotes: 3
Reputation: 47321
I think you can run a script to scan all files in the mounted cloudfuse,
(typically will be a cronjob)
then stored the results into a storage (memcache, database, etc...),
subsequently your PHP script can make use on the results
in order to keep the scan result up-to-date,
you can add-in hook to update the results when files updated / added / deleted
Upvotes: 1
Reputation: 16943
You can give a try to this:
function file_exists_timeout($file, $timeout) {
// try with both, as i mentioned in comment
// this is just a shot :( maybe it will works for you
ini_set('default_socket_timeout', $timeout);
stream_set_timeout($timeout);
$file = fopen($file, 'r');
if($file) {
fclose($file);
return true;
}else{
return false;
}
}
but i am not sure it will work for you.
Upvotes: 1
Reputation: 1899
You can use PHP's set_time_limit to limit the execution time of the "parent" script. http://php.net/manual/en/function.set-time-limit.php
Upvotes: -1