-
-
Notifications
You must be signed in to change notification settings - Fork 453
Multiple driver errors caused by invalid return type of driverRead()
#862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hello curious contributor !
|
I have the same issue with Memcached driver.
|
This behavior is very surprising as all tests would have been broken if such behavior would happens. Did you decorated Phpfastcache services or something ? If you see in (See |
Can you please post your full code implementation below ? Because this is the very first time report me this kind of issue that should be impossible to produce, especially with LOT of tests calling |
Hello, Before anything, I use the PHP-DI container for dependency injection that I build like this: $buildeur = new ContainerBuilder();
$buildeur->addDefinitions($pathToConfigFile);
$buildeur->enableCompilation(__ROOT_FOLDER . "/tmp");
$container = $buildeur->build(); The configuration file is of type: <?php
use DI\Container;
use Phpfastcache\CacheManager;
use Phpfastcache\Config\ConfigurationOption;
require __ROOT_FOLDER . "/vendor/autoload.php";
return [
CacheManager::class => function (Container $container) {
$instance = $container->get("ENV") === "dev" ? "Devnull" : "files";
CacheManager::setDefaultConfig(new ConfigurationOption([
"path" => $container->get("tmp.path")
]));
return CacheManager::getInstance($instance);
}
]; After that, so the compilation of the container has been defined, and phpfastcache and DI share the same tmp/ directory. //I have simplified the operation and removed the portions of code that are not necessary and do not interfere
$pdo = $container->get(PDO::class);
/** @var ExtendedCacheItemPoolInterface */
$cacheManager = $container->get(CacheManager::class);
$cacheString = "Maintenance";
$cacheItem = $cacheManager->getItem($cacheString);
if ($config["maintenance"] !== true && $pdo !== null) {
$cacheItem->set(false)->expiresAfter(3600 * 24);
$cacheManager->save($cacheItem);
} else {
if($pdo === null){
if($cacheItem->get() === false || $cacheItem->get() === null){
// send notification to discord
}
if(!$cacheItem->isHit()){
$cacheItem->set(true)->expiresAfter(3600 * 24);
}
$cacheManager->save($cacheItem);
}
} |
I think you are facing race condition issue with Also I suggest you a better approach with the CacheManager. Instead of calling: CacheManager::setDefaultConfig(new ConfigurationOption([
"path" => $container->get("tmp.path")
])); Try to do: return CacheManager::getInstance($instance, [
'path' => $container->get("tmp.path"),
'preventCacheSlams' => true,
]);
// OR Also try a more performant driver like |
I'll try your answer, however regarding the Redis driver, it takes, I guess a lot of memory space? |
Not at all, redis is one of the lightweight memory backend I know. It is
popular because of its efficiency and few ressources needed 😁
But first try to enable the option I suggested above.
|
Update after testing in production (where it crashes). The error is always launched having set the configuration as requested. I will try to switch to the Redis driver to see if it still happens or not. |
How many request per second do you have ? Can you invit me to talk on discord maybe ? :) |
This can go up I think to 10/15 requests per second at most. They are then limited by the capacity of my proxy and the traffic. Of course, here is my discord: ShockedPlot7560 # 9999 |
Added you, so we can discuss more clearly about your issue ! |
I need more information @aemla. What is the string returned exactly ? |
It can be reproduced by running it in a loop. I wrote a little example, it doesn't make any sense, but it throws the same error. 😁 In my original code, I am getting data from a database. Dump of that string: function test()
{
$array = [
['userId' => 1, 'data' => 'test'],
['userId' => 2, 'data' => 'test'],
['userId' => 3, 'data' => 'test'],
['userId' => 4, 'data' => 'test'],
['userId' => 5, 'data' => 'test'],
['userId' => 6, 'data' => 'test'],
['userId' => 7, 'data' => 'test'],
['userId' => 8, 'data' => 'test'],
['userId' => 9, 'data' => 'test'],
['userId' => 10, 'data' => 'test'],
['userId' => 11, 'data' => 'test'],
['userId' => 12, 'data' => 'test'],
['userId' => 13, 'data' => 'test'],
['userId' => 14, 'data' => 'test'],
['userId' => 15, 'data' => 'test'],
['userId' => 16, 'data' => 'test'],
['userId' => 17, 'data' => 'test'],
['userId' => 18, 'data' => 'test'],
['userId' => 19, 'data' => 'test'],
['userId' => 20, 'data' => 'test'],
['userId' => 21, 'data' => 'test'],
['userId' => 22, 'data' => 'test'],
];
$cache = CacheManager::getInstance('Memcached');
// The error only occurs when writing to the cache, so let's clear it before running the loop.
$cache->clear();
foreach ($array as $row) {
$this->getFromCache($cache, $row['userId'], $row['data']);
}
}
function getFromCache(ExtendedCacheItemPoolInterface $cache, $userId, $data)
{
$cachedString = $cache->getItem('dataById=' . $userId);
if (!$cachedString->isHit()) {
$cachedString->set($data)->expiresAfter(300);
$cache->save($cachedString);
return $cachedString->get();
} else {
return $cachedString->get();
}
} |
What version of php-memcached version are you using ? |
This error occurs only in 9.x, it works fine in 8.x. I am using LSMCD https://github.com/litespeedtech/lsmcd could this be the reason why it sometimes returns an empty string? |
This issue can be fixed by adding a check for an empty string. /**
* @param ExtendedCacheItemInterface $item
* @return null|array
*/
protected function driverRead(ExtendedCacheItemInterface $item): ?array
{
$val = $this->instance->get($item->getKey());
if ($val === false || $val === “”) {
return null;
}
return $val;
} |
"it works fine in 8.x" ? That's interesting. Did you tried in v8.1.x or previous one ? |
I understand now, I typed |
Ok ok, that make sense now. v8 was workin well because I previously made a weak validation:
But as of v9 I introduced (very) strict types everywhere this one can be problematic under some circumstances. |
Just out of curiosity tell me if replacing: if ($val === false) {
return null;
} by if (empty($val) || !\is_array($val)) {
return null;
} fixes your issue ? |
Yes, now it works fine. |
Roger that. I'll push a fix tonight and make a new release by the end of the week at late. |
driverRead()
driverRead()
Hi, we are still getting the same error. We are using version 9.1.2 and php 8.1.
Any tip? |
You seem to have concurrency issue as the file exists on disk but looks empty, very weird. Did you tried to enable |
will try and I report back. |
We have tried it and we still get the same error. I think the problem is in decode() function when calling unserialize() which one return false when it cant unserialize a string. |
Then you have a serious problem of I/O with your disk this is is not supposed to happens unless the file are corrupted or partially written which is a sign of a failing disk. I have multiple tests with this driver on the CI including concurrent writes and I'm not encountering this kind of issue. |
The problem is that this happens on multiple different servers and I really doubt that all servers have disk issues 😕 |
now we have tired to set |
Uh oh!
There was an error while loading. Please reload this page.
Configuration
Describe the bug
I don't really know the nature of the bug, but it seems to come from the File driver
Phpfastcache\Drivers\Files\Driver::driverRead()
To Reproduce
Code to reproduce the issue:
Driver used :
files
Stacktrace
The text was updated successfully, but these errors were encountered: