You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix#42: Refactoring, CacheInterface and add early expiration
* Refactoring and updates to CacheInterface
* Add cache stampede protection by early expiration
* Move CacheKeyNormalizer functionality to Cache
* Move dependency stores to CacheItem
* Refactoring of exceptions
* Fix comments to Cache and CacheInterface
* Change NullCache to PSR-16 implementation
* Fix ArrayCache and ArrayCacheTest
* Cleanup dependency classes
* Change callable signature on PSR-16 in getOrSet()
* Use early return in ttlToExpiration()
- Customizable way of serializing data. Out of the box PHP, JSON, Igbinary and custom callbacks are supported.
23
+
- Built on top of PSR-16, it can use any PSR-16 cache as a handler.
29
24
- Ability to set default TTL and key prefix per cache instance.
30
-
- Easy to implement your own cache backends extending from `SimpleCache`.
31
-
- Adds cache invalidation dependencies on top of PSR-16. Out of the box supports invalidation by tag and invalidation by
32
-
file modification time.
33
-
- Adds support for `add()` and `addMultiple()` operations additionally to PSR-16.
34
-
- Adds handy `getOrSet()` method additionally to PSR-16.
25
+
- Provides a built-in behavior to cache stampede prevention.
26
+
- Adds cache invalidation dependencies on top of PSR-16.
27
+
28
+
## Installation
35
29
36
-
## Configuration
37
-
38
-
There are two ways to get cache instance. If you need plain PSR-16 instance, you can simply create it:
30
+
The package could be installed with composer:
39
31
40
-
```php
41
-
$cache = new ApcuCache();
42
32
```
33
+
composer install yiisoft/cache
34
+
```
35
+
36
+
## Configuration
43
37
44
-
If you need additional features such as invalidation dependencies, `add()`, `addMultiple()` or `getOrSet()` you should
45
-
wrap PSR-16 cache instance with `Cache`:
38
+
There are two ways to get cache instance. If you need PSR-16 instance, you can simply create it:
46
39
47
40
```php
48
-
$cache = new Cache(new ApcuCache());
41
+
$arrayCache = new \Yiisoft\Cache\ArrayCache();
49
42
```
50
43
51
-
In order to change default serializer you can use `setSerializer()` method:
44
+
If you need a simpler yet more powerful way to cache values based on recomputation callbacks use `getOrSet()` and `remove()`, additional features such as invalidation dependencies and
45
+
"Probably early expiration" stampede prevention, you should wrap PSR-16 cache instance with `\Yiisoft\Cache\Cache`:
52
46
53
47
```php
54
-
$cache = new WinCache();
55
-
$cache->setSerializer(new JsonSerializer());
48
+
$cache = new \Yiisoft\Cache\Cache($arrayCache);
56
49
```
57
50
58
-
Default TTL could be set via `setDefaultTtl()`:
51
+
Set a default TTL:
59
52
60
53
```php
61
-
$cache = new ArrayCache();
62
-
$cache->setDefaultTtl(60 * 60); // 1 hour
54
+
$cache = new \Yiisoft\Cache\Cache($arrayCache, 60 * 60); // 1 hour
63
55
```
64
56
65
-
In order to set key prefix for a cache instance, use `setKeyPrefix()` method:
57
+
Set a key prefix:
66
58
67
59
```php
68
-
$cache = new Memcached();
69
-
$cache->setKeyPrefix('myapp');
60
+
$cache = new \Yiisoft\Cache\Cache($arrayCache, null, 'myapp');
70
61
```
71
62
72
-
## Usage
63
+
## General usage
73
64
74
-
Typical cache usage is the following:
65
+
Typical PSR-16 cache usage is the following:
75
66
76
67
```php
68
+
$cache = new \Yiisoft\Cache\ArrayCache();
69
+
$parameters = ['user_id' => 42];
77
70
$key = 'demo';
78
71
79
72
// try retrieving $data from cache
@@ -93,6 +86,8 @@ In order to delete value you can use:
93
86
94
87
```php
95
88
$cache->delete($key);
89
+
// Or all cache
90
+
$cache->clear();
96
91
```
97
92
98
93
To work with values in a more efficient manner, batch operations should be used:
@@ -105,59 +100,88 @@ When using extended cache i.e. PSR-16 cache wrapped with `\Yiisoft\Cache\Cache`,
105
100
is less repetitive:
106
101
107
102
```php
108
-
$parameters = ['user_id' => 42];
109
-
$data = $cache->getOrSet($key, function () use ($parameters) {
110
-
return $this->calculateSomething($parameters);
103
+
$cache = new \Yiisoft\Cache\Cache(new \Yiisoft\Cache\ArrayCache());
104
+
$key = ['top-products', $count = 10];
105
+
106
+
$data = $cache->getOrSet($key, function (\Psr\SimpleCache\CacheInterface $cache) use ($count) {
107
+
return getTopProductsFromDatabase($count);
111
108
}, 3600);
112
109
```
113
110
114
-
Additionally, `add()` and `addMultiple()` are avaialble. These methods work like `set()` and `setMultiple()` except
115
-
they store cache only if there is no existing value.
111
+
In order to delete value you can use:
112
+
113
+
```php
114
+
$cache->remove($key);
115
+
```
116
116
117
117
### Invalidation dependencies
118
118
119
-
When using extended cache i.e. PSR-16 cache wrapped with `\Yiisoft\Cache\Cache`, additionally to TTL for `set()`,
120
-
`setMultiple()`, `add()`, `addMultiple()` or `getOrSet()` methods you can specify a dependency that may trigger cache
121
-
invalidation. Below is an example using tag dependency:
119
+
When using `\Yiisoft\Cache\Cache`, additionally to TTL for `getOrSet()` method you can specify a dependency
120
+
that may trigger cache invalidation. Below is an example using tag dependency:
122
121
123
122
```php
123
+
/**
124
+
* @var callable $callable
125
+
* @var \Yiisoft\Cache\CacheInterface $cache
126
+
*/
127
+
128
+
use Yiisoft\Cache\Dependency\TagDependency;
129
+
124
130
// set multiple cache values marking both with a tag
125
-
$cache->set('item_42_price', 13, null, new TagDependency('item_42'));
126
-
$cache->set('item_42_total', 26, null, new TagDependency('item_42'));
131
+
$cache->getOrSet('item_42_price', $callable, null, new TagDependency('item_42'));
132
+
$cache->set('item_42_total', $callable, 3600, new TagDependency('item_42'));
127
133
128
134
// trigger invalidation by tag
129
135
TagDependency::invalidate($cache, 'item_42');
130
136
```
131
137
132
-
Out of there is file dependency that invalidates cache based on file modification time and callback dependency that
133
-
invalidates cache when callback result changes.
138
+
There is `Yiisoft\Cache\Dependency\FileDependency`that invalidates cache based on file modification time
139
+
and `Yiisoft\Cache\Dependency\CallbackDependency` that invalidates cache when callback result changes.
134
140
135
141
In order to implement your own dependency extend from `Yiisoft\Cache\Dependency\Dependency`.
136
142
137
-
You may combine multiple dependencies using `AnyDependency` or `AllDependencies`.
143
+
You may combine multiple dependencies using `Yiisoft\Cache\Dependency\AnyDependency`
144
+
or `Yiisoft\Cache\Dependency\AllDependencies`.
138
145
139
146
140
-
## Implementing your own cache backend
147
+
### Cache stampede prevention
148
+
149
+
[A cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) is a type of cascading failure that can occur when massively parallel computing systems with caching mechanisms come under very high load. This behaviour is sometimes also called dog-piling. The `\Yiisoft\Cache\Cache` uses a built-in "Probably early expiration" algorithm that prevents cache stampede.
150
+
This algorithm randomly fakes a cache miss for one user while others are still served the cached value.
151
+
You can control its behavior with the fifth optional parameter of `getOrSet()`, which is a float value called `$beta`.
152
+
By default, beta is `1.0`, which is sufficient in most cases. The higher the velue the earlier cache will be re-created.
0 commit comments