Description
Bug Report
Q | A |
---|---|
Flysystem Version | 3.29.1 |
Adapter Name | LocalFilesystemAdapter |
Adapter version | 3.29.0 |
Summary
Repeat calls to fileSize()
will return the same value if the file has been modified(by another process) between calls as the value is cached and not cleared by calling clearstatcache()
.
The is more or less the same issue that has previously been fixed in #1035 for file size.
The same issue is present if another process deletes a file or a directory, then concurrent calls to fileExists()
or directoryExists()
will be cached if it has existed on disk during the process. So it will continue to return true, even if the file/director has been deleted on disk.
Looking at https://www.php.net/manual/en/function.clearstatcache.php
Then this could be an issue for some of the other methods as well lastModified()
and possible others
In v1 fileSize()
, getTimestamp()
was part of the getMetaData()
method which called clearstatcache()
And the way to differentiate between a file and directory was to check the type inside the metadata
How to reproduce
Belows simulates what happens inside LocalFileSystemAdapterfileSize::fileSize()
when another process writes to a file
FileSize:
$file = 'fileSize.txt';
touch($file);
for($i = 0; $i < 5; $i++)
{
clearstatcache();
$beforeSize = filesize($file);
exec("echo 1 >> {$file}"); // This simulates another process that writes to the file
//clearstatcache(); // Uncomment to get the change in filesize
$afterSize = filesize($file);
if($beforeSize === $afterSize)
{
$strMessage = 'No change in file size.';
}
else
{
$strMessage = 'File size changed.';
}
echo "{$strMessage} Before: {$beforeSize} After: {$afterSize}".PHP_EOL;
sleep(1);
}
FileExists:
$file = 'filesize.txt';
touch($file);
$isFileBefore = is_file($file);
exec("rm -f {$file}");
$isFileAfter = is_file($file);
echo 'Before: '.($isFileBefore ? 'Exists' : 'Does Not Exist').' After: '.($isFileAfter ? 'Exists' : 'Does Not Exist').PHP_EOL;
clearstatcache();
echo "Clear stat cache".PHP_EOL;
echo "File exists: ".(is_file($file) ? 'Yes' : 'No').PHP_EOL;
Activity
LocalFilesystemAdapter. Call clearstatcache in several methods to avo…