yiisoft / cache Goto Github PK
View Code? Open in Web Editor NEWPSR-16 compatible cache library
Home Page: https://www.yiiframework.com/
License: BSD 3-Clause "New" or "Revised" License
PSR-16 compatible cache library
Home Page: https://www.yiiframework.com/
License: BSD 3-Clause "New" or "Revised" License
We need to consider introducing a driver that may proxy all the calls to a PSR-compatible caching library.
See #54
The current implementation only works when the data is already cached. In this case, every time the data is read from the cache, the algorithm calculates the expiration time and, if key is expired, recompute the cache. But imagine the cache is empty(for the first time) in high traffic. If we get a thousand simultaneous requests, they all hit the empty cache and the system calculates the data for all of them. Which again causes the cache stampede problem.
Is there a way to prevent the calculation of it for all requests in the first time, when our key and data are not cached?
For example lock the key or anything else ?
$now = microtime(true);
$delta = ceil(1000 * ($now - $this->updated)) / 1000;
$expired = $now - $delta * $beta * log(random_int(1, PHP_INT_MAX) / PHP_INT_MAX);
return $this->expiry <= $expired;
I was looking into this library, trying to work on some issues, and while working with it I noticed that the design of the library doesn’t feel right.
The first thing that bothers me is SimpleCache class, and that it adds additional functionality from the beginning (keys and values normalization, key prefixes, etc., what if you don’t need normalization or you want to handle it yourself) and those methods setValue, getValue etc. that each backend needs to implement instead of implementing interface methods, this is confusing. I think that different backend classes should just implement PSR interface as minimal as possible without any additional functionality and all additional things can be added to decorator (one or several) like Cache class that currently extends functionality.
It will have several significant benefits:
@samdark, so, what do you think of rewriting of the library a bit to this architecture? Is there any reason why we can’t do this or you don’t see any sense doing this? What if I try to implement it and we’ll see if it’s better than the current one?
It’s a question. Should setDefaultTtl() also accept DateInterval object to be consistent with set() method?
Many data caching with common TagDependency dependency with reusable option that is on.
Decrease Cache::multiGet calls from isChanged . Reusable property do not use in this method, but in parent class, in the same method reusable used.
When reusable options is on, caching timestamp data of the TagDependency in the static property.
Since there's no expiration for tags data, storage space could be exhausted. See yiisoft/yii2#17119
yii-core should not be required to use cache.
https://github.com/yiisoft/cache/blob/master/composer.json#L76
add()
and addMultiple()
work like set()
and setMultiple()
except they store cache only if there is no existing value.
Personally, I've never used it. Need opinions about removing these.
They're used in mailer, queue etc. https://github.com/yiisoft/serializer
Currently we can't use travis' container infrastructure since we require sudo
because of the FileCacheTest
.
As far as I can tell we're testing to if the FileCache
will properly fail in case it's set to a different owner.
Since our code is in a namespace and we use unqualified function calls to:
fileowner
posix_geteuid
unlink
We could simply mock fileowner()
and unlink()
for the test.
I think the code inside if ($this->persistentId !== null) {}
in \Yiisoft\Cache\Memcached::addServers
can never be executed https://github.com/yiisoft/cache/blob/master/src/Memcached.php#L88.
addServers()
method is called only from constructor and $this->persistentId
is always null
in this case.
The same is for the following blocks https://github.com/yiisoft/cache/blob/master/src/Memcached.php#L114
https://github.com/yiisoft/cache/blob/master/src/Memcached.php#L118
getMemcached()
is called from the constructor and then $this->cache
is never null
.
How about adding support to skip caching with negative $duration
in \yii\cache\CacheInterface::set()? (and multiSet(), and getOrSet(), of course)
As it done well in \yii\db\Query::cache() (since 2.0.14) - and it's pretty useful.
Of course we can use DummyCache to avoid caching, but it will affect ALL relevant cache-set calls.
My use case is flexiblе cache duration, which depends on environment, and which is different for different data.
So for now actually I have to do it like that:
if (Yii::$app->params['cacheDuration.catalogList'] >= 0) {
Yii::$app->getCache()->set($key, $value, Yii::$app->params['cacheTime.catalogList']);
}
It can be done simplier.
Q | A |
---|---|
Yii version | 2.0.14+ |
PHP version | any |
Operating system | any |
The get()
method must be compatible with psr/SimpleCache/CacheInterface::get()
interface CacheInterface
{
/**
* Fetches a value from the cache.
*
* @param string $key The unique key of this item in the cache.
* @param mixed $default Default value to return if the key does not exist.
*
* @return mixed The value of the item from the cache, or $default in case of cache miss.
*
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function get($key, $default = null);
}
Lines 299 to 305 in 81977ed
Why impose such restrictions on the prefix when the is_scalar
constraint is used for the key?
Inconsistency in behavior DbQueryDependency::method and QueryInterface::count
class DbQueryDependency extends Dependency
{
/**
* @var string|callable method which should be invoked in over the [[query]] object.
*
* If specified as a string an own query method with such name will be invoked, passing [[db]] value as its
* first argument. For example: `exists`, `all`.
*
* This field can be specified as a PHP callback of following signature:
*
* ```php
* function (QueryInterface $query, mixed $db) {
* //return mixed;
* }
* ```
*
* If not set - [[QueryInterface::one()]] will be used.
*/
public $method;
interface QueryInterface
/**
* Returns the number of records.
* @param string $q the COUNT expression. Defaults to '*'.
* @param Connection $db the database connection used to execute the query.
* If this parameter is not given, the `db` application component will be used.
* @return int number of records.
*/
public function count($q = '*', $db = null);
SQL error by this code
$cacheProperties = [
'dependency' => [
'class' => \yii\caching\DbQueryDependency::class,
'query' => $query,
'method' => 'count'
],
'duration' => 60 * 60 * 24
];
if ($this->beginCache($key, $cacheProperties)) {
// ...
$this->endCache();
}
PSR-16 specifies keys to be strings. We are supporting any type via serialization.
$updated_at = rand(1, 10);
echo $updated_at . PHP_EOL;
$dependency = new \yii\caching\ExpressionDependency(
[
//'expression' => 'date("Y-m-d H:i:s")', // normal work
'expression' => '$this->params', // use 'params' not work
'params' => ['updated_at' => $updated_at]
]
);
$cacheKey = 'goods_view';
$date = Yii::$app->cache->getOrSet($cacheKey, function () {
return [rand(20, 100)];
}, 3600, $dependency);
print_r($date) ;
exit();
Also, when changing the expression, you must use './yii cache/flush-all' to clear the cache to take effect.
How to use both expression and params parameters correctly ?
Q | A |
---|---|
Yii version | 2.0.15.1? |
PHP version | 5.5 |
Operating system | mac os |
The main point is to achieve proper extension dependencies resolving via Composer.
The store for tags in a complex project can be different from the store for the cache itself.
It is necessary to give the opportunity to set the store for tags:
$cache->getOrSet('item_42_price', $callable, null, new TagDependency('item_42', $tagCache));
The Symfony cache allows you to set up the tag store via configuration. It would be convenient if we could specify the tag store in the settings of the cache itself.
Remove travis if it exists
`
use Yiisoft\Cache\ArrayCache;
$cache1 = new ArrayCache();
$cache2 = new ArrayCache();
$cache1->set('test', 'sddsbsdbdsbds');
var_dump($cache1->has('test')); //True
var_dump($cache2->has('test')); //False
`
So maybe private array $cache must be static? Otherwise ArrayCache work differently compared with FIleCache, Memcached, APCu etc
According to PSR-16 some characters must not be used as keys:
The following characters are reserved for future extensions and MUST NOT be supported by implementing libraries:
{}()/\@:
Psr\SimpleCache\CacheInterface
requires an exception to be thrown for invalid keys:
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
*/
public function get($key, $default = null);
So as I understand the spec any key containing one of the above characters MUST also be considered invalid and lead to an exception.
This affects all other cache backends (apc, ...)
Currently clear cleans up whole cache not taking prefix into account. We probably should change that.
We need to consider implementing PSR-6 and using it as PSR-16 via adapter.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.