Skip to content

Commit 2764007

Browse files
authored
Merge pull request #6578 from nikolajlauridsen/v15/cache-docs
V15: Cache seeding docs
2 parents fb6a238 + fbf2b96 commit 2764007

File tree

7 files changed

+348
-57
lines changed

7 files changed

+348
-57
lines changed

15/umbraco-cms/.gitbook.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,4 @@ redirects:
104104
extending/backoffice-tours: extending/README.md
105105
tutorials/creating-a-backoffice-tour: tutorials/overview.md
106106
extending/packages/types-of-packages: extending/packages/README.md
107+
reference/configuration/nucachesettings: reference/configuration/cache-settings.md

15/umbraco-cms/SUMMARY.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
* [Health Check Guides](extending/health-check/guides/README.md)
4848
* [Content Content Security Policy (CSP)](extending/health-check/guides/contentsecuritypolicy.md)
4949
* [Creating a Custom Database Table](extending/database.md)
50+
* [Creating a Custom Seed Key Provider](extending/creating-custom-seed-key-provider.md)
5051

5152
## Reference
5253

@@ -70,7 +71,7 @@
7071
* [Logging settings](reference/configuration/loggingsettings.md)
7172
* [Maximum Upload Size Settings](reference/configuration/maximumuploadsizesettings.md)
7273
* [Models builder settings](reference/configuration/modelsbuildersettings.md)
73-
* [NuCache Settings](reference/configuration/nucachesettings.md)
74+
* [Cache Settings](reference/configuration/cache-settings.md)
7475
* [Package Migration](reference/configuration/packagemigrationsettings.md)
7576
* [Plugins settings](reference/configuration/pluginssettings.md)
7677
* [Request handler settings](reference/configuration/requesthandlersettings.md)
@@ -92,6 +93,7 @@
9293
* [Using Umbraco services](reference/management/using-services/README.md)
9394
* [Content Type Service](reference/management/using-services/contenttypeservice.md)
9495
* [Cache & Distributed Cache](reference/cache/README.md)
96+
* [Cache Seeding](reference/cache/cache-seeding.md)
9597
* [Examples](reference/cache/examples/README.md)
9698
* [Working with caching](reference/cache/examples/tags.md)
9799

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
description: A guide to creating a custom seed key provider for Umbraco
3+
---
4+
5+
# Creating a Custom Seed Key Provider
6+
7+
Umbraco uses a lazy loaded cache, which means that content is loaded into the cache on an as-needed basis. However, you may need specific content to always be in the cache. To achieve this you can implement your own custom seed key providers.
8+
9+
There are two types of seed key providers: `IDocumentSeedKeyProvider` for documents and `IMediaSeedKeyProvider` for media. As these interfaces are identical only `IDocumentSeedKeyProvider` is demonstrated in this article.
10+
11+
{% hint style="warning" %}
12+
Seed keys are cached and calculated once. Any documents created after the site has started will not be included in the seed keys until after a server restart.
13+
{% endhint %}
14+
15+
## Implementation
16+
17+
This example implements a `IDocumentSeedKeyProvider` which seeds all the children of a node, in this case blog posts.
18+
19+
1. Create a new class called `BlogSeedKeyProvider` that implements `IDocumentSeedKeyProvider`.
20+
21+
```csharp
22+
using Umbraco.Cms.Infrastructure.HybridCache;
23+
24+
namespace MySite.SeedKeyProviders;
25+
26+
public class BlogSeedKeyProvider : IDocumentSeedKeyProvider
27+
{
28+
public ISet<Guid> GetSeedKeys()
29+
{
30+
}
31+
}
32+
```
33+
34+
Next we'll inject the `IDocumentNavigationQueryService` in order to get the children of the blog node.
35+
36+
```csharp
37+
using Umbraco.Cms.Core.Services.Navigation;
38+
using Umbraco.Cms.Infrastructure.HybridCache;
39+
40+
namespace MySite.SeedKeyProviders;
41+
42+
public class BlogSeedKeyProvider : IDocumentSeedKeyProvider
43+
{
44+
private readonly IDocumentNavigationQueryService _documentNavigationQueryService;
45+
46+
public BlogSeedKeyProvider(IDocumentNavigationQueryService documentNavigationQueryService)
47+
=> _documentNavigationQueryService = documentNavigationQueryService;
48+
49+
{...}
50+
```
51+
52+
3. Parse a hardcoded string to a GUID.
53+
4. Use the `IDocumentNavigationQueryService` to get the children of the blog node.
54+
5. Return their keys as a `HashSet`.
55+
56+
```csharp
57+
public ISet<Guid> GetSeedKeys()
58+
{
59+
var blogRoot = Guid.Parse("a5fdb22d-b7f2-4a59-8c4e-46ed86bde56c");
60+
61+
if (_documentNavigationQueryService.TryGetChildrenKeys(blogRoot, out IEnumerable<Guid> blogPostKeys))
62+
{
63+
return new HashSet<Guid>(blogPostKeys);
64+
}
65+
66+
return new HashSet<Guid>();
67+
}
68+
```
69+
Since this returns it as a set, and all the sets get unioned, we do not have to worry about duplicates.
70+
71+
The final class looks like this:
72+
73+
```csharp
74+
using Umbraco.Cms.Core.Services.Navigation;
75+
using Umbraco.Cms.Infrastructure.HybridCache;
76+
77+
namespace MySite.SeedKeyProviders;
78+
79+
public class BlogSeedKeyProvider : IDocumentSeedKeyProvider
80+
{
81+
private readonly IDocumentNavigationQueryService _documentNavigationQueryService;
82+
83+
public BlogSeedKeyProvider(IDocumentNavigationQueryService documentNavigationQueryService)
84+
=> _documentNavigationQueryService = documentNavigationQueryService;
85+
86+
public ISet<Guid> GetSeedKeys()
87+
{
88+
var blogRoot = Guid.Parse("a5fdb22d-b7f2-4a59-8c4e-46ed86bde56c");
89+
90+
if (_documentNavigationQueryService.TryGetChildrenKeys(blogRoot, out IEnumerable<Guid> blogPostKeys))
91+
{
92+
return new HashSet<Guid>(blogPostKeys);
93+
}
94+
95+
return new HashSet<Guid>();
96+
}
97+
}
98+
```
99+
100+
### Registering the Seed Key Provider
101+
102+
Now that the `BlogSeedKeyProvider` is implemented, it must be registered in the `Startup` class.
103+
104+
```csharp
105+
using MySite.SeedKeyProviders;
106+
using Umbraco.Cms.Infrastructure.DependencyInjection;
107+
using Umbraco.Cms.Infrastructure.HybridCache;
108+
109+
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
110+
111+
builder.Services.AddSingleton<IDocumentSeedKeyProvider, BlogSeedKeyProvider>();
112+
{...}
113+
```
114+
115+
All blogpost will now be seeded into the cache on startup, and will always be present in the cache.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
description: Information about cache seeding
3+
---
4+
5+
# Cache Seeding
6+
7+
Umbraco uses a lazy loaded cache, meaning content is loaded into the cache on an as-needed basis. Whenever a piece of content is shown on the website for the first time it first needs to be loaded into the cache.
8+
9+
Loading the content into the cache causes a delay. This delay is dependent on the latency between your server and your database, but is generally minimal.
10+
For certain pages, like the front page, you may not want this delay to be there. The role of cache seeding is meant to solve this issue.
11+
12+
## How it works
13+
14+
Cache seeding is based on the concept of an `ISeedKeyProvider`. The role of the seed key provider is to specify what keys need to be seeded.
15+
16+
There are two types of seed key providers: an `IDocumentSeedKeyProvider` specifying which document should be seeded, and an `IMediaSeedKeyProvider` specifying which media should be seeded.
17+
18+
During startup, all the `ISeedKeyProviders` are run, and the keys they return are seeded into their respective caches, `IPublishedContentCache` for documents, and `IPublishedMediaCache` for media. Additionally, whenever a document or media is changed, the cache will immediately be updated with the changed content. This ensures that the content is always present in the cache.
19+
20+
Whenever a piece of content is changed, the seeded keys must be checked, to see if the updated content was seeded. Because of the need the check all seeded keys, Umbraco caches the keys themselves during startup. This means that if you have a dynamic seed key provider, any newly added content will not be considered seeded until the server restarts. For instance, when seeding by Document Type any new content using the specified Document Type will not be seeded until the server is restarted.
21+
22+
## Seed key providers
23+
24+
### Default implementations
25+
26+
By default, Umbraco ships with two seed key providers for documents, and one for media.
27+
28+
For documents, the `ContentTypeSeedKeyProvider` seeds all documents of the given Document Types specified in the `appSettings.json` file.
29+
30+
For documents and media, the `BreadthFirstKeyProvider` does a breadth-first traversal of the content and media tree respectively. This will seed N number of content specified in the `appSettings.json` file.
31+
32+
The default seed key provider configuration can be found in the [cache settings section.](../configuration/cache-settings.md).
33+
34+
### Custom seed key providers
35+
36+
It is also possible to implement custom seed key providers. These are run alongside the default seed key providers on startup.
37+
38+
The returned keys of all the seed key providers are unioned into a single set. This means there will be no duplicates.
39+
40+
As mentioned above the provided keys are cached. Only the keys returned at startup will be considered seeded until the server restarts and the provider is rerun.
41+
42+
For a specific example of implementing a custom seed key provider, see [Creating a Custom Seed Key Provider](../extending/creating-custom-seed-key-provider.md).
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
description: Information on the Cache settings section
3+
---
4+
5+
# Cache Settings
6+
7+
{% hint style="info" %}
8+
Are you looking for the **NuCache Settings**?
9+
10+
While most cache configurations are under the `Umbraco:CMS:Cache` settings node, a few remain under `Umbraco:CMS:NuCache`. [Learn more about this at the bottom of this article](#nucache-settings).
11+
{% endhint %}
12+
13+
## HybridCacheOptions
14+
15+
Umbraco's cache is implemented using Microsofts `HybridCache`, which also has its own settings. For more information [see the HybridCache documentation](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/hybrid?view=aspnetcore-9.0#options).
16+
17+
### MaximumPayLoadBytes
18+
19+
One `HybridCache` setting of particular interest is the `MaximumPayloadBytes` setting. This setting specifies the maximum size of a cache entry in bytes and replaces the `BTreeBlockSize` setting from NuCache.
20+
The default from Microsoft is 1MB. However, this limit could quickly be reached, especially when using multiple languages or property editors like the block grid.
21+
To avoid this Umbraco overrides the setting to 100MB by default. You can also configure this manually using a composer:
22+
23+
```csharp
24+
using Microsoft.Extensions.Caching.Hybrid;
25+
using Umbraco.Cms.Core.Composing;
26+
27+
namespace MySite.Caching;
28+
29+
public class ConfigureCacheComposer : IComposer
30+
{
31+
public void Compose(IUmbracoBuilder builder)
32+
{
33+
builder.Services.AddOptions<HybridCacheOptions>().Configure(x =>
34+
{
35+
x.MaximumPayloadBytes = 1024 * 1024 * 10; // 10MB
36+
});
37+
}
38+
}
39+
```
40+
41+
## Seeding settings
42+
43+
The Seeding settings allow you to specify which content should be seeded into your cache. For more information on cache seeding see the [Cache Seeding.](../cache/cache-seeding.md) article.
44+
45+
### ContentTypeKeys
46+
47+
The `ContentTypeKeys` setting specifies which Document Types should be seeded into the cache. The setting is a comma-separated list of Document Type keys.
48+
49+
```json
50+
"Umbraco": {
51+
"CMS": {
52+
"Cache": {
53+
"ContentTypeKeys": ["e811405e-0190-4d3e-8387-7558521eec81", "419e89fb-8cff-4549-a074-9f8a30687828", "e0d71146-8205-4cf4-8236-f982b392259f"],
54+
}
55+
}
56+
}
57+
```
58+
59+
### DocumentBreadthFirstSeedCount
60+
61+
The `DocumentBreadthFirstSeedCount` setting specifies how many documents should be seeded into the cache when doing a breadth-first traversal. The default value is 100.
62+
63+
```json
64+
"Umbraco": {
65+
"CMS": {
66+
"Cache": {
67+
"DocumentBreadthFirstSeedCount": 500
68+
}
69+
}
70+
}
71+
```
72+
73+
## MediaBreadthFirstSeedCount
74+
75+
The `MediaBreadthFirstSeedCount` setting specifies how many media items should be seeded into the cache when doing a breadth-first traversal. The default value is 100.
76+
77+
```json
78+
"Umbraco": {
79+
"CMS": {
80+
"Cache": {
81+
"MediaBreadthFirstSeedCount": 500
82+
}
83+
}
84+
}
85+
```
86+
87+
## Cache Entry settings
88+
89+
The Entry settings allow you to specify how long cache entries should be kept. The cache entry settings are identical for documents and media.
90+
91+
## LocalCacheDuration
92+
93+
Specifies the duration for which cache entries should be kept in the local memory cache. The default value is 24 hours.
94+
95+
```json
96+
"Umbraco": {
97+
"CMS": {
98+
"Cache": {
99+
"Entry": {
100+
"Document": {
101+
"LocalCacheDuration": "2.00:00:00"
102+
},
103+
"Media": {
104+
"LocalCacheDuration": "50.00:00:00"
105+
}
106+
}
107+
}
108+
}
109+
}
110+
```
111+
112+
## RemoteCacheDuration
113+
114+
Specifies the duration that cache entries should be kept in the remote cache, second level cache. This setting is only relevant if a second-level cache is configured. The default value is 1 year.
115+
116+
```json
117+
"Umbraco": {
118+
"CMS": {
119+
"Cache": {
120+
"Entry": {
121+
"Document": {
122+
"RemoteCacheDuration": "100.00:00:00"
123+
},
124+
"Media": {
125+
"RemoteCacheDuration": "150.00:00:00"
126+
}
127+
}
128+
}
129+
}
130+
}
131+
```
132+
133+
## SeedCacheDuration
134+
135+
Specifies the duration for which seeded cache entries should be kept in the cache. The default value is 1 year.
136+
137+
```json
138+
"Umbraco": {
139+
"CMS": {
140+
"Cache": {
141+
"Entry": {
142+
"Document": {
143+
"SeedCacheDuration": "200.00:00:00"
144+
},
145+
"Media": {
146+
"SeedCacheDuration": "250.00:00:00"
147+
}
148+
}
149+
}
150+
}
151+
}
152+
```
153+
154+
# NuCache Settings
155+
156+
For backward compatibility reasons, certain settings are under the `Umbraco:CMS:NuCache` settings node.
157+
158+
## UsePagedSqlQuery
159+
160+
Setting `UsePagedSqlQuery` to `False` your project will use the `Fetch` method instead of the `QueryPaged` method when rebuilding the NuCache files. This will increase performance on bigger Umbraco websites with a lot of content when rebuilding the NuCache.
161+
162+
```json
163+
"Umbraco": {
164+
"CMS": {
165+
"NuCache": {
166+
"UsePagedSqlQuery": false
167+
}
168+
}
169+
}
170+
171+
```
172+
## SqlPageSize
173+
174+
Specifying the `SqlPageSize` will change the size of the paged SQL queries. The default value is 1000.
175+
176+
```json
177+
"Umbraco": {
178+
"CMS": {
179+
"NuCache": {
180+
"SqlPageSize": 500
181+
}
182+
}
183+
}
184+
```

0 commit comments

Comments
 (0)