PHPSocialNetwork / phpfastcache

A high-performance backend cache system. It is intended for use in speeding up dynamic web applications by alleviating database load. Well implemented, it can drops the database load to almost nothing, yielding faster page load times for users, better resource utilization. It is simple yet powerful.
https://www.phpfastcache.com
MIT License
2.38k stars 451 forks source link

mkdir(): File exists #740

Closed maraouf closed 4 years ago

maraouf commented 4 years ago

Hello,

Configuration

Describe the bug I'm not sure if this is a bug, so I'll frame it as a question until proven otherwise

So my project registers shutdown errors using the following

register_shutdown_function("FatalExceptionHandler");

And FatalExceptionHandler, gets the last error and log it in a file using log4php

$error = error_get_last();
if (isset($error) && !empty($error)) {
        $logger->error("Fatal error occurred\n" . DumpLog($error));

The problem is I'm receivig this error frequently

2020-05-15T10:32:10 ERROR Default ---- vo10899ktcgidmu836cp2rd1ho 4633 main ---- Fatal error occurred array(4) { ["type"]=> int(2) ["message"]=> string(20) "mkdir(): File exists" ["file"]=> string(109) "/assets/vendor/phpfastcache/phpfastcache/lib/Phpfastcache/Core/Pool/IO/IOHelperTrait.php" ["line"]=> int(93) }

Tracing this inside PHPFastCache library, this code is what generating the error

if (!$skip && !\is_dir($path) && @!\mkdir($path, $this->getDefaultChmod(), true) && !\is_dir($path)) {
            throw new PhpfastcacheIOException(
                'Path "' . $path . '" is not writable, please set a chmod 0777 or any writable permission and make sure to make use of an absolute path !'
            );
        }

However, the PhpfastcacheIOException is not thrown as it is not logged anywhere with log4php, so something wrong is happending in the if condition itself and it doesnt render the exception

To Reproduce Unable to reproduce in test environment, it happens when published.

Screenshots Not applicable

Additional context All information I have written above

github-actions[bot] commented 4 years ago

Hello curious contributor ! Since it seems to be your first contribution, make sure that you've been:

Geolim4 commented 4 years ago

Hello,

Please reformat your issue using the appropriate template please, I'm not a magician 🤷‍♂️

Cheers, Georges

maraouf commented 4 years ago

My apologies, original post updated with the needed format

Geolim4 commented 4 years ago

Hello,

You are may facing an issue with Chown/Chmod. Please be sure that your web server user is allowed to write on the cache directory you specified. This part is heavily tested so I'm doubting about and issue in Phpfastcache, especially when your issue looks like many others with this kind of issue :)

Cheers, Georges

maraouf commented 4 years ago

Hello, I understand, it is just am trying to figure out the issue for my setup and configuraton

My configuration for the cache is as follows:

$defaultDriver = 'Files';
$Psr16Adapter = new Psr16Adapter($defaultDriver, ['path' => $_SERVER['DOCUMENT_ROOT'] . '/cache']);
$cache = $Psr16Adapter;

So all files should be written in cache directory right? and if permissions for the cache directory is 777 with apache as owner process will be sufficient?

Geolim4 commented 4 years ago

It should be sufficient indeed, but do you have CLI scripts running along your web app ?

maraouf commented 4 years ago

The webserver is hosting multiple websites, configured as different vhosts on Apache, one of these sites is running Wordpress (I'm not sure if Wordpress includes CLI or not). But for this specific website, it is not running any CLI scripts.

Geolim4 commented 4 years ago

Did you configured the securityKey option correctly ? Also, try to enable the secureFileManipulation option too.

maraouf commented 4 years ago

Hello,

Thanks alot, those 2 keys are not set. Can you guide me for the documentation on how to implement them for Psr16Adapter

I didn't find useful documentation mapping to this setup in version 8 $Psr16Adapter = new Psr16Adapter($defaultDriver, ['path' => $_SERVER['DOCUMENT_ROOT'] . '/cache']);

Geolim4 commented 4 years ago

What IDE are you using by curiosity ?

maraouf commented 4 years ago

PhpStorm 2020.1.1 Build #PS-201.7223.96, built on April 30, 2020

Geolim4 commented 4 years ago

Ok, then take a look to Psr16 constructor: You can either use a string as first argument or an "ExtendedCacheItemPoolInterface" object.

Second argument is a standard "Config" object.

maraouf commented 4 years ago

Yes, thanks for the info, I already reached the point of passing the config. I should have clarified further

So the code is now setup like this

$cacheDriver = 'Files';
$cacheConfig = new Phpfastcache\Config\ConfigurationOption([
    'path' => $_SERVER['DOCUMENT_ROOT'] . '/cache/',
    'securityKey' => 'cache',
    'secureFileManipulation' => true
]);
$Psr16Adapter = new Phpfastcache\Helper\Psr16Adapter($cacheDriver, $cacheConfig);
$cache = $Psr16Adapter;

and the problem is

Fatal error: Uncaught Phpfastcache\Exceptions\PhpfastcacheInvalidConfigurationException: Invalid option(s) for the config Phpfastcache\Config\ConfigurationOption: securityKey, secureFileManipulation in /assets/vendor/phpfastcache/phpfastcache/lib/Phpfastcache/Config/ConfigurationOption.php:104

So my question if you have any pointers to check since the documentation for this part is scarse

Geolim4 commented 4 years ago

This is normal since those options aren't "global options" but "Files Options":

https://github.com/PHPSocialNetwork/phpfastcache/wiki/%5BV4%CB%96%5D-Configuration-Options

Use "\Phpfastcache\Drivers\Files\Config" object instead.

maraouf commented 4 years ago

Ok, I'm writing this here so if anyone encounters this issue or need further documentation

The code now looks like this

$xmlconfig = simplexml_load_file($_SERVER['DOCUMENT_ROOT'] . 'configuration_file_name_redacted');
if (isset($xmlconfig->phpFastCacheSecureKey)) {
    $phpFastCacheSecureKey = ((string)$xmlconfig->phpFastCacheSecureKey);
    if (!isset($phpFastCacheSecureKey) || empty($phpFastCacheSecureKey)) {
        throw new Exception(Strings\ErrorMessages::$ERROR_1318);
    }
}else{
    throw new Exception(Strings\ErrorMessages::$ERROR_1321);
}

$cacheDriver = 'Files';
$cacheConfig = new \Phpfastcache\Drivers\Files\Config([
    'path' => $_SERVER['DOCUMENT_ROOT'] . '/cache/',
    'securityKey' => $phpFastCacheSecureKey,
    'secureFileManipulation' => true,
    'cacheFileExtension' => 'cache'
]);
$Psr16Adapter = new Phpfastcache\Helper\Psr16Adapter($cacheDriver, $cacheConfig);
$cache = $Psr16Adapter;

Which is working as expected on test environment, and files are being written correctly

Will proceed with publishing the fix for prod environment, and will monitor for tomorrow, if the issue disappeared or still exists.

Thanks for your help, cheers

Screen Shot 2020-05-16 at 1 25 34 AM

Geolim4 commented 4 years ago

You should setup a different securityKey per host !!

maraouf commented 4 years ago

Thanks, adjusted the code snippet above to read from website global config file

maraouf commented 4 years ago

Has been monitoring the case for the past few days, and it seems the missing keys of securityKey and secureFileManipulation has solved the issue and now it is writing the files correctly to the cache directory.

So I'm heading off to close this case, and thanks alot for your help @Geolim4.