Skip to content
This repository was archived by the owner on May 18, 2025. It is now read-only.

Commit 9a3b4dc

Browse files
committed
🐛 bolt num not initialized in all cases
✨ added pagemethod boost 🚧 extracted demo code 📝 improved readme
1 parent 666b048 commit 9a3b4dc

24 files changed

+213
-339
lines changed

README.md

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
[![Maintainability](https://flat.badgen.net/codeclimate/maintainability/bnomei/kirby3-boost)](https://codeclimate.com/github/bnomei/kirby3-boost)
88
[![Twitter](https://flat.badgen.net/badge/twitter/bnomei?color=66d9ef)](https://twitter.com/bnomei)
99

10-
Boost the speed of Kirby by having content files of pages (mem-)cached, with automatic unique ID, fast lookup and Tiny-URL.
10+
Boost the speed of Kirby by having content files of pages cached, with automatic unique ID, fast lookup and Tiny-URL.
1111

1212
## Commerical Usage
1313

@@ -28,10 +28,10 @@ If you have a lot of page objects (1000+) with or without relations to each othe
2828
- It provides a very fast lookup for page objects via id, diruri or the unique id.
2929
- It provides you with a tiny-url for page objects that have an unique id.
3030

31-
> This plugin is an enhanced combination of [Page Memcached](https://github.com/bnomei/kirby3-page-memcached), [AutoID](https://github.com/bnomei/kirby3-autoid/) and [Bolt](https://github.com/bnomei/kirby3-bolt).
32-
3331
## Setup
3432

33+
For each template you want to be cached you need to add the field to your blueprint AND use a model to add the content cache logic.
34+
3535
**site/blueprints/pages/default.yml**
3636
```yml
3737
preset: page
@@ -86,8 +86,30 @@ $page = boost($boostId); // will use fastest internally
8686
```
8787

8888
### Modified timestamp from cache
89+
90+
This will try to get the modified timestamp from cache. If the page object content can be cached but currently was not, it will force a content cache write. It will return the modified timestamp of a page object or if it does not exist it will return `null`.
91+
8992
```php
90-
$page = modified($somePageId);
93+
$page = modified($somePageId); // faster
94+
```
95+
96+
### Debug === read from content file (not from cache)
97+
98+
If you set Kirbys global debug option to `true` the plugin will not read the content cache but from the content file on disk. But it will write to the content cache so you can get debug messages if anything goes wrong with that process.
99+
100+
### Forcing a content cache update
101+
102+
You can force writing to the cache manually but doing that should not be necessary.
103+
104+
```php
105+
// write content cache of a single page
106+
$page->boost();
107+
108+
// write content cache of all pages in a Pages collection
109+
$page->children()->boost();
110+
111+
// write content cache of all pages in site index
112+
site()->boost();
91113
```
92114

93115
## Cache
@@ -96,36 +118,47 @@ $page = modified($somePageId);
96118

97119
How much and if you gain anything regarding performance depends on the hardware. All your content files must fit within the memory limitation. If you run into errors consider increasing the server settings or choose a different cache driver.
98120

99-
| Defaults for | Memcached | APCu | Redis | SQLite |
100-
|----|----|----|----|----|
101-
| max memory size | 64MB | 32MB | 0 (none) | 0 (none) |
102-
| size of key/value pair | 1MB | 4MB | 512MB | 0 (none) |
121+
| Defaults for | Memcached | APCu | Redis | MySQL | SQLite |
122+
|----|----|----|----|----|----|
123+
| max memory size | 64MB | 32MB | 0 (none) | 0 (none) | 0 (none) |
124+
| size of key/value pair | 1MB | 4MB | 512MB | 0 (none) | 0 (none) |
103125

104-
Kirby has [built in support](https://getkirby.com/docs/reference/system/options/cache#cache-driver) for File, Apcu, Memcached and Memory. I have created additional cache drivers for [SQLite](https://github.com/bnomei/kirby3-sqlite-cachedriver) and [Redis](https://github.com/bnomei/kirby3-redis-cachedriver).
126+
Kirby has [built in support](https://getkirby.com/docs/reference/system/options/cache#cache-driver) for File, Apcu, Memcached and Memory. I have created additional cache drivers for [MySQL](https://github.com/bnomei/kirby3-mysql-cachedriver), [SQLite](https://github.com/bnomei/kirby3-sqlite-cachedriver) and [Redis](https://github.com/bnomei/kirby3-redis-cachedriver).
105127

106128
### Benchmark
107129

108130
The included benchmark can help you make an educated guess which is the faster cache driver. The only way to make sure is measuring in production.
109-
Be aware that this will create and remove 2000 items cached. The benchmark will try to perform as many get operations within given timeframe (default 2 seconds per cache). The higher results are better.
131+
Be aware that this will create and remove 1000 items cached. The benchmark will try to perform as many get operations within given timeframe (default 1 second per cache). The higher results are better.
110132

111133
```php
112134
// use helpers to generate caches to compare
113135
// rough performance level is based on my tests
114136
$caches = [
137+
// better
115138
\Bnomei\BoostCache::memory(), // 100
116139
\Bnomei\BoostCache::sqlite(), // 80
117140
\Bnomei\BoostCache::apcu(), // 40
141+
\Bnomei\BoostCache::mysql(), // ??
118142
\Bnomei\BoostCache::redis(), // 30
119143
\Bnomei\BoostCache::file(), // 10
120144
\Bnomei\BoostCache::memcached(), // 4
145+
// worse
121146
];
122147
// run the benchmark
123148
var_dump(\Bnomei\CacheBenchmark::run($caches));
124149
```
125150

126151
Memory Cache Driver will probably perform best but caches in memory only for current request and that is not really useful for this plugin. SQLite Cache Driver will perform very well since everything will be in one file and I optimized the read/write with [pragmas](https://github.com/bnomei/kirby3-sqlite-cachedriver/blob/bc3ccf56cefff7fd6b0908573ce2b4f09365c353/index.php#L20) and [wal journal mode](https://github.com/bnomei/kirby3-sqlite-cachedriver/blob/bc3ccf56cefff7fd6b0908573ce2b4f09365c353/index.php#L34).
127152

128-
But do not take my word for it. Run the benchmark on your production server.
153+
> The MySQL Cache Driver is still in development but I expect it to on par with Redis and thus to be a lot SLOWER than the SQLite Cache Driver.
154+
155+
You can find the benchmark and demos running on server sponsored by **Kirbyzone** here:
156+
- [Benchmark with all Drivers](https://kirby3-boost.bnomei.com)
157+
- [Demo using SQLite Cache Driver](https://kirby3-boost-sqlite.bnomei.com)
158+
- [Demo using MySQL Cache Driver](https://kirby3-boost-mysql.bnomei.com)
159+
- [Demo using Redis Cache Driver](https://kirby3-boost-redis.bnomei.com)
160+
161+
But do not take my word for it. Download the plugin and run the benchmark on your production server.
129162

130163
### Config
131164

@@ -144,7 +177,7 @@ return [
144177
'prefix' => 'boost',
145178
],
146179

147-
// example memached
180+
// example memcached
148181
'bnomei.boost.cache' => [
149182
'type' => 'memcached',
150183
'prefix' => 'boost',
@@ -199,6 +232,14 @@ You can use this plugin instead of AutoID if you did not use autoid in site obje
199232
- Replace calls to `autoid()` with `boost()` in php code
200233
- Replace `->fromAutoID()` with `->fromBoostID()` in php code
201234

235+
## History
236+
237+
This plugin is an enhanced combination of
238+
- [Page Memcached](https://github.com/bnomei/kirby3-page-memcached),
239+
- [Page SQLite](https://github.com/bnomei/kirby3-page-sqlite),
240+
- [AutoID](https://github.com/bnomei/kirby3-autoid/) and
241+
- [Bolt](https://github.com/bnomei/kirby3-bolt).
242+
202243
## Disclaimer
203244

204245
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-boost/issues/new).

classes/Bolt.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,35 @@ public function __construct(?Page $parent = null)
5252
$this->modelFiles = array_map(static function ($value) use ($extension) {
5353
return $value . '.' . $extension;
5454
}, array_keys(Page::$models));
55+
56+
if (option('debug')) {
57+
$this->flush();
58+
}
5559
}
5660

5761
private static function cache()
5862
{
5963
return BoostCache::singleton();
6064
}
6165

66+
public function flush()
67+
{
68+
static::$idToPage = [];
69+
70+
// this would flush content cache as well or depending on cache driver everything
71+
// do NOT do this ever!
72+
// // BoostCache::singleton()->flush();
73+
74+
return true;
75+
}
76+
6277
public function lookup(string $id, bool $cache = true): ?Page
6378
{
6479
$lookup = A::get(static::$idToPage, $id);
6580
if (!$lookup && $cache && static::cache()) {
6681
if ($diruri = static::cache()->get(crc32($id) . '-bolt')) {
82+
// bolt will ignore caches with invalid paths and update them automatically
83+
// it does not need to be flushed ever
6784
if ($page = $this->findByID($diruri, false)) {
6885
$this->pushLookup($id, $page);
6986
$lookup = $page;
@@ -107,7 +124,9 @@ public function findByID(string $id, bool $cache = true): ?Page
107124
$this->root .= '/_drafts';
108125
continue;
109126
}
110-
$partWithoutNum = array_reverse(explode(Dir::$numSeparator, $part))[0];
127+
$numSplit = array_reverse(explode(Dir::$numSeparator, $part));
128+
$partWithoutNum = $numSplit[0];
129+
$num = count($numSplit) > 1 ? $numSplit[1] : null;
111130
$treeid = $treeid ? $treeid . '/' . $partWithoutNum : $partWithoutNum;
112131
$page = $this->lookup($treeid, $cache);
113132
if ($page) {
@@ -116,13 +135,12 @@ public function findByID(string $id, bool $cache = true): ?Page
116135
continue;
117136
}
118137

119-
120138
$params = [
121139
'root' => null,
122140
'dirname' => null,
123141
'parent' => $parent,
124142
'slug' => $partWithoutNum,
125-
'num' => null,
143+
'num' => $num,
126144
'model' => null,
127145
];
128146

@@ -163,6 +181,7 @@ public function findByID(string $id, bool $cache = true): ?Page
163181
$template = str_replace('.' . $this->extension, '', $modelFile);
164182
$params['template'] = $template;
165183
$params['model'] = $template;
184+
var_dump('DOUNDdddxxx');
166185
break;
167186
}
168187
}

classes/BoostIndex.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function flush(): bool
7373
if ($this->cache()) {
7474
return $this->cache()->set('index', [], $this->expire);
7575
}
76-
return false;
76+
return true;
7777
}
7878

7979
public function findByBoostId(string $boostid): ?Page
@@ -145,7 +145,17 @@ public static function tinyurl($id): string
145145

146146
public static function modified(string $id): ?int
147147
{
148-
return BoostCache::singleton()->get(crc32($id) . '-modified');
148+
$modified = BoostCache::singleton()->get(crc32($id) . '-modified');
149+
if ($modified) {
150+
return $modified;
151+
}
152+
153+
if ($page = \bolt($id)) {
154+
$page->boost(); // force cache update
155+
return $page->modified();
156+
}
157+
158+
return null;
149159
}
150160

151161
public static function page(string $id): ?Page

classes/CacheBenchmark.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
final class CacheBenchmark
1212
{
13-
private static function benchmark($cache, int $seconds = 2, $count = 2000, $contentLength = 128): int
13+
private static function benchmark($cache, int $seconds = 1, $count = 1000, $contentLength = 128): int
1414
{
1515
for ($i = 0; $i < $count; $i++) {
1616
$cache->set('CacheBenchmark-' . $i, Str::random($contentLength), 0);
@@ -34,7 +34,7 @@ private static function benchmark($cache, int $seconds = 2, $count = 2000, $cont
3434
return count($values);
3535
}
3636

37-
public static function run(array $caches = [], int $seconds = 2, $count = 2000, $contentLength = 128): array
37+
public static function run(array $caches = [], int $seconds = 1, $count = 1000, $contentLength = 128): array
3838
{
3939
$caches = $caches ?? [ BoostCache::file() ];
4040

0 commit comments

Comments
 (0)