Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bnomei/kirby3-lapse
Cache any data until set expiration time
https://github.com/bnomei/kirby3-lapse
automatic cache expire key-value kirby3 kirby3-cms kirby3-plugin memcached modified multi-language-support performance
Last synced: 14 days ago
JSON representation
Cache any data until set expiration time
- Host: GitHub
- URL: https://github.com/bnomei/kirby3-lapse
- Owner: bnomei
- License: mit
- Created: 2018-08-31T10:38:53.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2024-10-24T17:05:35.000Z (21 days ago)
- Last Synced: 2024-10-25T16:08:53.636Z (20 days ago)
- Topics: automatic, cache, expire, key-value, kirby3, kirby3-cms, kirby3-plugin, memcached, modified, multi-language-support, performance
- Language: PHP
- Homepage: https://forum.getkirby.com/t/kirby3-lapse-cache-any-data-until-set-expiration-time-with-automatic-keys/23586
- Size: 256 KB
- Stars: 20
- Watchers: 4
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: readme.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Kirby3 Lapse
![Release](https://flat.badgen.net/packagist/v/bnomei/kirby3-lapse?color=ae81ff)
![Downloads](https://flat.badgen.net/packagist/dt/bnomei/kirby3-lapse?color=272822)
[![Build Status](https://flat.badgen.net/travis/bnomei/kirby3-lapse)](https://travis-ci.com/bnomei/kirby3-lapse)
[![Coverage Status](https://flat.badgen.net/coveralls/c/github/bnomei/kirby3-lapse)](https://coveralls.io/github/bnomei/kirby3-lapse)
[![Maintainability](https://flat.badgen.net/codeclimate/maintainability/bnomei/kirby3-lapse)](https://codeclimate.com/github/bnomei/kirby3-lapse)
[![Twitter](https://flat.badgen.net/badge/twitter/bnomei?color=66d9ef)](https://twitter.com/bnomei)Cache any data until set expiration time (with automatic keys).
## Commercial Usage
>
> Support open source!
> This plugin is free but if you use it in a commercial project please consider to sponsor me or make a donation.
> If my work helped you to make some cash it seems fair to me that I might get a little reward as well, right?
> Be kind. Share a little. Thanks.
> ‐ Bruno
>| M | O | N | E | Y |
|---|----|---|---|---|
| [Github sponsor](https://github.com/sponsors/bnomei) | [Patreon](https://patreon.com/bnomei) | [Buy Me a Coffee](https://buymeacoff.ee/bnomei) | [Paypal dontation](https://www.paypal.me/bnomei/15) | [Hire me](mailto:[email protected]?subject=Kirby) |## Installation
- unzip [master.zip](https://github.com/bnomei/kirby3-lapse/archive/master.zip) as folder `site/plugins/kirby3-lapse` or
- `git submodule add https://github.com/bnomei/kirby3-lapse.git site/plugins/kirby3-lapse` or
- `composer require bnomei/kirby3-lapse`## Usecase
The Kirby Pages-Cache can cache the output of Page Templates. It devalidates **all** cache files if any Object in the Panel is changed. This is a good choice if you do not make changes often. But if you do make changes often you need a cache that knows what has been modified and which caches to devalidate and which not.
Sometimes you can not cache the complete Page since...
- it contains a [form](https://github.com/mzur/kirby-uniform) with a csrf hash,
- you use [content security headers](https://github.com/bnomei/kirby3-security-headers) with nouces,
- build and cache data for a logicless templating system like [handlebars](https://github.com/bnomei/kirby3-handlebars) or
- you want to cache data from an external source like an API.Lapse was build to do exactly that: **Cache any data until set expiration time.**
## Usage Examples
### Example 1: get/set
```php
$key = hash('xxh3', $page->url()); // unique key
// to delay data creation until need use a callback. do not use a plain array or object.
$data = function () {
return [1, 2, 3];
};
$data = lapse($key, $data);
```### Example 2: with custom expiration time
```php
$key = hash('xxh3', $page->url()); // unique key
$expires = 5; // in minutes. default: 0 aka infinite
$data = function () {
return [1, 2, 3];
};
$data = lapse($key, $data, $expires);
```### Example 3: page object
```php
$data = lapse(hash('xxh3', $page->url()), function () use ($kirby, $site, $page) {
// create some data
return [
'author' => site()->author(),
'title' => $page->title(),
'text' => $page->text()->kirbytext(),
'url' => $page->url(),
];
});
```### Remove by Key
```php
$key = hash('xxh3', $page->url()); // unique key
$wasRemoved = \Bnomei\Lapse::rm($key);
```## Static Cache helper - lapseStatic()
Sometimes you need to cache things only for the current request like
when [reusing Kirbys Collections](https://forum.getkirby.com/t/remember-this-caching-in-kirby/23705/4#solution-with-a-static-cache-3)
. The `lapseStatic()`-helper makes things like that a bit easier. The closure to generate the data will only be called
once, set its return value to a static cache and every recurring call to the collection will get the cached collection
back from static memory array.**site/plugins/example/index.php**
```php
[
// collections have to be a closure that is why it is wrapped in a fn
'recent-courses' => fn() => lapseStatic(
'recent-courses', // key
function () { // value
return page('courses')->children()->listed()->sortBy('name')->limit(10);
}
)
]);
```## Clever keys
### Unique but not modified
Caches use a string value as key to store and later retrieve the data. The key is usually a hash of the objects id plus
some meta data like the contents language. Storing data related to a Page using the `$key = hash('xxh3', $page->url());` will
work just fine. It takes care of the language if you use a multi-language setup since the language is included in the
url. But it will expire only if you provide a fixed time or devalidate it yourself.### Modified
The solution is to include the modification timestamp of every object related to the data. So if you store the result of
a Page Object with Images being rendered you need to include the modification timestamp of all of these. That will cause
the creation of a new cache every time your source changes.#### Basic
```php
$keys = [ $page->url().$page->modified() ];
foreach($page->images() as $image) {
$keys[] = $image->id().$image->modified();
}
$key = hash('xxh3', implode($keys));
```#### Objects
Since version 2 of this plugin you can also forward any of these and the key will be magically created for you.
- Page-Objects,
- File-Objects and FileVersion-Objects (aka Thumbs),
- Collections or
- the Site-Object```php
$objects = [$page, $page->images()];
$data = lapse($objects, ...)
```#### Multi-language support
The keys created by the plugin are [tagged with the current language](https://github.com/bnomei/kirby3-lapse/blob/master/classes/Lapse.php#L181). You will get a different cache value for each language.
#### AutoID or BoostID
If you use the [AutoID plugin](https://github.com/bnomei/kirby3-autoid) or [Boost plugin](https://github.com/bnomei/kirby3-boost) the modification timestamps will be retrieved at almost zero-cpu-cost and not causing the file to be checked on disk.## FAQ
### Infinite cache duration by default
Unless you set an expiration when using `lapse()` the cache file will never devalidate. This is because the plugin is intended to be used with keys defining the expiration like `$key = hash('xxh3', $page->id().$page->modified());`.
```php
$expires = 5; // in minutes. default: 0 aka infinite
$data = lapse($key, $data, $expires);
```When using Memcache or APCu you need to limit the maximum number of caches created since you have a very limited amount if memory of 64MB at default. You can set a limit at `bnomei.lapse.indexLimit` to something like `300`. But be aware that this makes writing to the cache a tiny bit slower since the plugins internal index must be updated.
### No cache when debugging
When Kirbys global debug config is set to `true` the **complete** plugin cache will be flushed and no caches will be created. This will make you live easier – trust me.
### Kirby Field-Objects and serialization
The plugin uses the default Kirby serialization of objects and since memory references are lost anyway all Kirby Field-Objects are stored by calling their `->value()` method. The File-Cache uses a json format.
### Migrating from v1 of this plugin
- `$force` param has been removed: use proper keys.
- all settings have been removed: they are not needed anymore like explained above.## Performance
### Use crc32 to generate the hash
`xxh3` is the [fastest](https://php.watch/versions/8.1/xxHash) non cryptographic hashing hashing algorithm in PHP 8.1 . The keys for lapse do not need to be encrypted.
### Cache Driver
For best performance set the **global** [cache driver](https://getkirby.com/docs/reference/system/options/cache#cache-driver) to one using the servers memory not files on the harddisk (even on SSDs). Memcache or ApcuCache can be activated on most hosting environments but rarely are by default. Also see `bnomei.lapse.indexLimit` setting explained above. My [Redis Cache Driver](https://github.com/bnomei/kirby3-redis-cachedriver) and [SQLite Cache Driver](https://github.com/bnomei/kirby3-sqlite-cachedriver) are faster than other cache drivers and have no memory limit. In all other cases use the very fast [PHP Cache Driver](https://github.com/bnomei/kirby3-php-cachedriver) or APCu.```php
return [
'cache' => [
'driver' => 'apcu', // php, redis, sqlite
],
];
```## Examples
```php
// lapse v1 could already do this:
// store data until objects are modified with optional expire
$data = lapse(
$page->id().$page->modified(),
['some', 'kind', 'of', 'data'],
60*24*7 // one week
);// now it can create magic cache keys from kirby objects
$data = lapse(
$page, // key with modification date created by lapse based on object
function () use ($page) {
return [
'title' => $page->title(),
];
}
);// or from an collection of pages or files
$collection = collection('mycollection');
$data = lapse(
$collection, // this will turn into a key taking modification date of all objects into consideration
function () use ($collection) {
return [ /*...*/ ];
}
);// or from an array combining all these
$data = lapse(
['myhash', $page, $page->children()->images(), $collection, $site], // will create key from array of objects
function () use ($site, $page, $collection) {
return [
// will not break serialization => automatically store ->value() of fields
'author' => $site->author(),
'title' => $page->title(),
'hero' => $page->children()->images()->first()->srcset()->html(),
'count' => $collection->count(),
];
}
);// remove by dynamic key
$wasRemoved = \Bnomei\Lapse::rm(
['myhash', $page, $page->children()->images(), $collection, $site]
);
```> 🏎️ if you use autoid or boost the modified lookups will be at almost zero-cpu cost.
## Cancel the caching
If you want to cancel the caching you can throw the `LapseCancelException` in the closure. This will prevent the caching of the data and return `null`.
```php
$data = lapse(
$page,
function () use ($page) {
if ($page->isUnpublished()) {
// do not cache unpublished pages
throw new \Bnomei\LapseCancelException();
}
return $page->title()->value();
}
);
// $data === null for unpublished pages
```## Disclaimer
This plugin is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it in a production environment. If you find any issues, please [create a new issue](https://github.com/bnomei/kirby3-lapse/issues/new).
## License
[MIT](https://opensource.org/licenses/MIT)
It is discouraged to use this plugin in any project that promotes racism, sexism, homophobia, animal abuse, violence or any other form of hate speech.
## Credits
based on V2 version of
- https://github.com/jenstornell/kirby-time-cache