-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: bnomei <[email protected]>
- Loading branch information
Showing
9 changed files
with
1,625 additions
and
892 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,6 +94,22 @@ return [ | |
'bnomei.boost.patch.files' => true, // default: true | ||
``` | ||
|
||
### Directories Inventory Cache (experimental) | ||
|
||
Starting with version 5.0 the plugin will cache the inventory of directories. For that to be possible it will patch the `Kirby\Filesystem\Dir` class. It will automatically flush the cache if you edit pages in the panel, just like the core [pages cache](https://getkirby.com/docs/reference/system/options/cache). It's enabled by default but you can disable it if you want to like the following. | ||
|
||
**index.php** | ||
```php | ||
// after bootstrap and before kirby runs | ||
\Bnomei\BoostDirInventory::singleton(['enabled' => false]); | ||
``` | ||
|
||
You could also flush the cache manually. | ||
|
||
```php | ||
\Bnomei\BoostDirInventory::singleton()->flush(); | ||
``` | ||
|
||
### Pages Field Alternative | ||
|
||
This plugin provided a pages field alternative based on the multiselect field and optimized for performance. | ||
|
@@ -264,35 +280,6 @@ var_dump(\Bnomei\CacheBenchmark::run($caches, 1, site()->index()->count())); // | |
|
||
But do not take my word for it. Download the plugin, set realistic benchmark options and run the benchmark on your production server. | ||
|
||
### Interactive Demo | ||
|
||
I created an interactive demo to compare various cache drivers and prove how much your website can be boosted. It kind of ended up as a love-letter to the <a class="underline" href="https://github.com/getkirby/kql">KQL Plugin</a> as well. You can find the benchmark and interactive demos here: | ||
|
||
- [Benchmark with all Drivers](https://kirby3-boost.bnomei.com) | ||
- [Demo using PHP Cache Driver](https://kirby3-boost-php.bnomei.com) | ||
- [Demo using APCu Cache Driver](https://kirby3-boost-apcu.bnomei.com) | ||
- [Demo using MySQL Cache Driver](https://kirby3-boost-mysql.bnomei.com) | ||
- [Demo using Null Cache Driver](https://kirby3-boost-null.bnomei.com). This setup behaves like having the boost plugin NOT active at all. | ||
- [Demo using Redis Cache Driver](https://kirby3-boost-redis.bnomei.com) | ||
- [Demo using SQLite Cache Driver](https://kirby3-boost-sqlite.bnomei.com) | ||
|
||
### Headless Demo | ||
|
||
You can either use this interactive playground or a tool like HTTPie, Insomnia, PAW or Postman to connect to the public API of the demos. Queries are sent to the public API endpoint of the <a class="underline" href="https://github.com/getkirby/kql">KQL Plugin</a>. This means you can compare response times between cache drivers easily. | ||
|
||
**HTTPie examples** | ||
```shell | ||
# get benchmark comparing the cachedrivers | ||
http POST https://kirby3-boost.bnomei.com/benchmark --json | ||
|
||
# get boostmark for a specific cache driver | ||
http POST https://kirby3-boost-apcu.bnomei.com/boostmark --json | ||
|
||
# compare apcu and sqlite | ||
http POST https://kirby3-boost-apcu.bnomei.com/api/query -a [email protected]:kirby3boost < myquery.json | ||
http POST https://kirby3-boost-sqlite.bnomei.com/api/query -a [email protected]:kirby3boost < myquery.json | ||
``` | ||
|
||
### Config | ||
|
||
Once you know which driver you want to use you can set the plugin cache options. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<?php | ||
|
||
namespace Bnomei; | ||
|
||
use Kirby\Filesystem\Dir; | ||
use Kirby\Toolkit\A; | ||
use ReflectionClass; | ||
|
||
class BoostDirInventory | ||
{ | ||
private ?array $data; | ||
|
||
private bool $enabled; | ||
|
||
private bool $isDirty; | ||
|
||
public function __construct(array $options = []) | ||
{ | ||
$this->enabled = A::get($options, 'enabled', true); | ||
$this->isDirty = false; | ||
$this->data = []; | ||
|
||
if ($this->enabled) { | ||
self::patchDirClass(); | ||
|
||
if (file_exists($this->file())) { | ||
// $this->data = file_exists($this->file()) ? json_decode(file_get_contents($this->file()), true) : []; | ||
$this->data = include $this->file(); | ||
} | ||
} | ||
} | ||
|
||
public function __destruct() | ||
{ | ||
if (! $this->isDirty || ! $this->enabled) { | ||
return; | ||
} | ||
|
||
// file_put_contents($this->file(), json_encode($this->data, JSON_PRETTY_PRINT)); | ||
file_put_contents( | ||
$this->file(), | ||
'<?php'.PHP_EOL.' return '.var_export($this->data, true).';', | ||
LOCK_EX | ||
) !== false; | ||
if (function_exists('opcache_invalidate')) { | ||
opcache_invalidate($this->file()); | ||
} | ||
} | ||
|
||
public function file(): string | ||
{ | ||
$cache = BoostCache::singleton(); | ||
if ($cache && method_exists($cache, 'root')) { | ||
return $cache->root().'/boost-dir-inventory.cache.php'; | ||
} | ||
|
||
return __DIR__.'/../boost-dir-inventory.cache.php'; | ||
} | ||
|
||
public function get($key): ?array | ||
{ | ||
if (! $this->enabled) { | ||
return null; | ||
} | ||
|
||
$key = $this->key($key); | ||
|
||
return A::get($this->data, $key); | ||
} | ||
|
||
public function set($key, ?array $input = null): void | ||
{ | ||
if (! $this->enabled) { | ||
return; | ||
} | ||
|
||
$this->isDirty = true; | ||
$key = $this->key($key); | ||
$this->data[$key] = $input; | ||
} | ||
|
||
public static function flush(): void | ||
{ | ||
$instance = static::singleton(); | ||
if (file_exists($instance->file())) { | ||
unlink($instance->file()); | ||
} | ||
|
||
$instance->data = []; | ||
$instance->isDirty = true; | ||
} | ||
|
||
public static function singleton(array $options = []): self | ||
{ | ||
static $instance; | ||
|
||
return $instance ?: $instance = new self($options); | ||
} | ||
|
||
private function key($key): string | ||
{ | ||
return is_array($key) ? hash('xxh3', print_r($key, true)) : $key; | ||
} | ||
|
||
public static function patchDirClass(): void | ||
{ | ||
$reflection = new ReflectionClass(Dir::class); | ||
$file = $reflection->getFileName(); | ||
|
||
$content = file_get_contents($file); | ||
$head = <<<'CODE' | ||
$items = static::read($dir, $contentIgnore); | ||
CODE; | ||
|
||
$head_new = <<<'CODE' | ||
$cacheKey = func_get_args(); | ||
if ($cache = \Bnomei\BoostDirInventory::singleton()->get($cacheKey)) { | ||
return $cache; | ||
} | ||
$items = static::read($dir, $contentIgnore); | ||
CODE; | ||
$foot = <<<'CODE' | ||
return $inventory; | ||
} | ||
CODE; | ||
$foot_new = <<<'CODE' | ||
\Bnomei\BoostDirInventory::singleton()->set($cacheKey, $inventory); | ||
return $inventory; | ||
} | ||
CODE; | ||
if (strpos($content, $head_new) !== false) { | ||
return; | ||
} | ||
$content = str_replace($head, $head_new, $content); | ||
$content = str_replace($foot, $foot_new, $content); | ||
file_put_contents($file, $content); | ||
|
||
if (function_exists('opcache_invalidate')) { | ||
opcache_invalidate($file); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.