Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 11 additions & 42 deletions docs/infrastructure_and_maintenance/cache/persistence_cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@

## Transparent cache

With the persistence cache, like with the HTTP cache, [[= product_name =]] tries to follow principles of transparent caching.
This can shortly be described as a cache which is invisible to the end user (admin/editors) of [[= product_name =]] where content is always returned *fresh*.
In other words, there should be no need to manually clear the cache like it was frequently the case with eZ Publish 4.x.
This is possible thanks to an interface that follows CRUD (Create Read Update Delete) operations per domain.
With the persistence cache, like with the HTTP cache, [[= product_name =]] follows the principles of transparent caching.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed an outdated eZ Publish 4.x mention 🙈

The cache is invisible to the end user (admin/editors) of [[= product_name =]] and content is always returned *fresh*.

## What is cached?

Expand All @@ -46,11 +44,11 @@

!!! note

Current implementation uses Symfony cache.
Current implementation uses [Symfony application cache]([[= symfony_doc =]]/cache.html#system-cache-and-application-cache).
It technically supports the following cache backends: [APCu, Array, Chain, Doctrine, Filesystem, PDO & Doctrine DBAL, Php Array, Proxy, Redis]([[= symfony_doc =]]/components/cache/cache_pools.html#creating-cache-pools).
[[= product_name =]] officially supports only using Filesystem for single server and Redis for clustered setups.
[[= product_name =]] officially supports only using Filesystem for single server and Redis/Valkey for clustered setups.

Use of Redis as shared cache back end is a requirement for use in clustering setup.
Use of [Redis/Valkey](#redisvalkey) as shared cache backend is a requirement for use in clustering setup.
For an overview of this feature, see [Clustering](clustering.md).
Filesystem adapters, for example, are **not** intended to be used over a shared filesystem.

Expand Down Expand Up @@ -233,7 +231,7 @@

#### With dependency injection

In your Symfony services configuration you can define that you require the cache service in your configuration like so:
In your Symfony services configuration you can inject the cache service in your configuration like so:

``` yaml
# yml configuration
Expand All @@ -244,41 +242,23 @@

This service is an instance of `Symfony\Component\Cache\Adapter\TagAwareAdapterInterface`, which extends the `Psr\Cache\CacheItemPoolInterface` interface with tagging functionality.

#### With service container

Like any other service, you can also get the cache service with the [service container](php_api.md#service-container) like so:

``` php
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

// Getting the cache service in PHP

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ibexa.cache_pool is a private service (Public: no) so it's not possible to retrieve it from the container anymore

~/Desktop/Sites/v5 main +1 !174 ?19 ❯ php bin/console debug:container ibexa.cache_pool                                                                                                               24.4.0 13:21:18

 // This service is a private alias for the service
 // Ibexa\Core\Persistence\Cache\Adapter\TransactionalInMemoryCacheAdapter

Information for Service "Ibexa\Core\Persistence\Cache\Adapter\TransactionalInMemoryCacheAdapter"
================================================================================================

 Internal proxy adapter invalidating our isolated in-memory cache, and defer shared pool changes during transactions.

 ---------------- ---------------------------------------------------------------------------------------------------------------------------------
  Option           Value
 ---------------- ---------------------------------------------------------------------------------------------------------------------------------
  Service ID       Ibexa\Core\Persistence\Cache\Adapter\TransactionalInMemoryCacheAdapter
  Class            Ibexa\Core\Persistence\Cache\Adapter\TransactionalInMemoryCacheAdapter
  Tags             container.decorator (id: ibexa.cache_pool, inner: Ibexa\Core\Persistence\Cache\Adapter\TransactionalInMemoryCacheAdapter.inner)
  Public           no
  Synthetic        no
  Lazy             yes
  Shared           yes
  Abstract         no
  Autowired        no
  Autoconfigured   no


/** @var ContainerInterface $container */
$pool = $container->get('ibexa.cache_pool');
/** @var TagAwareAdapterInterface $pool */
```

### Using the cache service

Example usage of the cache service:

``` php
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrote this to avoid getting a service from the container directly - that's not recommended anymore

// Example
/**
* @var TagAwareAdapterInterface $pool
* @var ContainerInterface $container
* @var int $id
*/
$cacheItem = $pool->getItem("myApp-object-{$id}");
if ($cacheItem->isHit()) {
return $cacheItem->get();
}

$myObject = $container->get('my_app.backend_service')->loadObject($id);
$myObject = $myAppCustomService->loadObject($id);
$cacheItem->set($myObject);
$cacheItem->tag(['myApp-category-' . $myObject->categoryId]);
$pool->save($cacheItem);
Expand All @@ -290,21 +270,8 @@

### Clearing persistence cache

!!! caution "Always clear the persistence with `cache:pool:clear` command"

Running `php bin/console cache:clear` doesn't clear the persistence cache, even when you use a filesystem-based cache pool.

You must always clear the persistence cache by running:

```bash
php bin/console cache:pool:clear <cache-pool>
```

The default cache pool is named `cache.tagaware.filesystem`.
The default cache pool when running Redis or Valkey is named `cache.redis`.
If you have customized the persistence cache configuration, the name of your cache pool might be different.

Persistence cache prefixes it's cache using "ibx-". Clearing persistence cache can thus be done in the following ways:
Persistence cache uses the `ibx-` prefix, declared as a container parameter called `ibexa.core.persistence.cache.tag_prefix`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/ibexa/core/blob/6.0/src/lib/Resources/settings/storage_engines/cache.yml#L13

The part about clearing the cache with the command was out of place here, it's about API usage.

Added a link for people searching how to clear the cache manually.

You can clear the cache as in the following example:

``` php
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
Expand All @@ -322,3 +289,5 @@
// Symfony cache is tag-based, so you can clear all cache related to a content item like this:
$pool->invalidateTags(["c-$contentId"]);
```

To learn how to clear persistence cache when not using the PHP API, see [Clear persistence cache](devops.md#clear-persistence-cache).

Check notice on line 293 in docs/infrastructure_and_maintenance/cache/persistence_cache.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/cache/persistence_cache.md#L293

[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.
Raw output
{"message": "[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.", "location": {"path": "docs/infrastructure_and_maintenance/cache/persistence_cache.md", "range": {"start": {"line": 293, "column": 46}}}, "severity": "INFO"}
73 changes: 56 additions & 17 deletions docs/infrastructure_and_maintenance/devops.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,81 @@

## Cache clearing

### Clearing file cache using the Symfony cache:clear command
[[= product_name =]] contains multiple layer of caching that you can clear independently from each other:

Symfony provides a command for clearing cache.
It deletes all file-based caches, which mainly consist of a Twig template, a [service container](php_api.md#service-container), and the Symfony route cache, but also everything else stored in the cache folder.
Out of the box on a single-server setup this includes Content cache.
- [Clear system cache](#clear-system-cache)
- [Clear persistence cache](#clear-persistence-cache)
- [Clear HTTP cache](#clear-http-cache)

For further information on the command's use, see its help text:
### Clear system cache

[System cache]([[= symfony_doc =]]/cache.html#system-cache-and-application-cache) is separate for every [Symfony environment](environments.md) and stores information derivable from source code like compiled container, routes, or optimized classes.

To clear the system cache, execute the `cache:clear` command on [every web server](clustering.md) running [[= product_name =]].

To specify an environment, pass it by using either the `--env` option or the `APP_ENV` variable.
Both the examples below clear the system cache for the `prod` environment:

- `APP_ENV=prod php bin/console cache:clear`
- `php bin/console cache:clear --env=prod`

When neither the `--env` option nor the `APP_ENV` variable is set, `cache:clear` clears the system cache for the `dev` environment by default.

Don't run `cache:clear` as root as it can lead to issues with file ownership.

!!! caution "Symfony 7.4 behavior change"

Starting with Symfony 7.4, running `php bin/console cache:clear` or `rm -rf var/cache/*` clears only the system cache, even when you use a filesystem-based cache pool for [persistence cache](#clear-persistence-cache).
You must always clear the persistence cache separately.

#### Clearing system cache manually

During development, you can clear the system cache manually by running:

``` bash
php bin/console --env=prod cache:clear -h
rm -rf var/cache/*
```

!!! note
!!! caution "Don't clear system cache manually on production"

If you don't specify an environment, by default `cache:clear` clears the cache for the `dev` environment.
If you want to clear it for `prod` you need to use the `--env=prod` option.
Manually clearing the system cache doesn't warm up the cache, resulting in a significant performance drop on the first request.
To avoid this, you must not clear the cache manually in a production environment.

!!! caution "Clustering"
### Clear persistence cache

In [clustering](clustering.md) setup (with several web servers), the command to clear file cache needs to be executed on every web server.
[Persistence cache](persistence_cache.md) stores information about application data.

To clear the persistence cache, you must run:

``` bash
php bin/console cache:pool:clear <cache-pool>
```

The default cache pool is named `cache.tagaware.filesystem`.

Check notice on line 59 in docs/infrastructure_and_maintenance/devops.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/devops.md#L59

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/infrastructure_and_maintenance/devops.md", "range": {"start": {"line": 59, "column": 24}}}, "severity": "INFO"}
The default cache pool when running Redis or Valkey is named `cache.redis`.

Check notice on line 60 in docs/infrastructure_and_maintenance/devops.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/devops.md#L60

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/infrastructure_and_maintenance/devops.md", "range": {"start": {"line": 60, "column": 53}}}, "severity": "INFO"}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you customized the persistence cache configuration, the name of your cache pool might be different.

#### Clearing persistence cache manually

During development, when using a filesystem-based cache pool, you can clear the application cache by running:

Check notice on line 65 in docs/infrastructure_and_maintenance/devops.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/devops.md#L65

[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.
Raw output
{"message": "[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.", "location": {"path": "docs/infrastructure_and_maintenance/devops.md", "range": {"start": {"line": 65, "column": 21}}}, "severity": "INFO"}

```bash
rm -rf var/share/*
```

### Clearing content cache on a cluster setup
### Clear HTTP cache

Check notice on line 71 in docs/infrastructure_and_maintenance/devops.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/devops.md#L71

[Ibexa.SentenceCapitalizationInHeadings] Use sentence-style capitalization in headings
Raw output
{"message": "[Ibexa.SentenceCapitalizationInHeadings] Use sentence-style capitalization in headings", "location": {"path": "docs/infrastructure_and_maintenance/devops.md", "range": {"start": {"line": 71, "column": 5}}}, "severity": "INFO"}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a dedicated HTTP cache section to cover all types of caches.


For a [cluster](clustering.md) setup, the content cache ([HTTP cache](http_cache.md) and [Persistence cache](persistence_cache.md)) must be set up to be shared among the servers.
While all relevant cache is cleared for you on repository changes when using the APIs, there might be times where you need to clear cache manually:
[HTTP cache](http_cache.md) uses reverse proxies like Varnish or Fastly to store application responses controlled by [HTTP Cache headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control).

- Varnish: [Cache purge](reverse_proxy.md#using-varnish-or-fastly)
- Persistence Cache: [Using Cache service](persistence_cache.md#using-cache-service)
To clear the HTTP cache, see [Purging from command line](content_aware_cache.md#purging-from-command-line).

## Web Debug Toolbar

As of [[= product_name =]] v4.5, the [Symfony Web Debug Toolbar]([[= symfony_doc =]]/profiler.html) is no longer installed by default.
To install it, run the following command:

```bash
composer require symfony/debug-pack
composer require --dev symfony/debug-pack

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--dev was missing, and it's crucial!

```

After you have installed Symfony Web Debug Toolbar, it's available when running [[= product_name =]] in the `dev` environment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,34 +56,7 @@ They can be manually removed from `composer.json` now.

## How to clear the cache properly?

Clearing cache is covered by our [documentation](devops.md#cache-clearing), it applies to file and content (HTTP/persistence) cache.

Useful commands:

- clearing Symfony cache

```bash
php bin/console cache:clear --env prod
```

- clearing Redis/Valkey cache

```bash
php bin/console cache:pool:clear cache.redis
```

- clearing the Symfony cache manually

```bash
rm -rf var/cache/*
rm -rf var/share/*
```

!!! caution "Clearing cache manually"

Manual cache clearing should be executed with caution, as it doesn't warm up the cache.
It results in a significant performance drop on first request, so it shouldn't be called on a production environment.
Besides, it could lead to issues with file ownership after running `cache:clear` as a root.
See [Cache clearing](devops.md#cache-clearing) for information how to clear system, persistence, and HTTP caches.

## Where should I place my configuration files?

Expand Down
6 changes: 3 additions & 3 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ parameters:
path: code_samples/_inline_php/content_management/field_types/type_and_value/4d9e52e02d6e226f71015653d598f662f6b4d4eb0af9e99b4c49d5389af19671.php

-
message: '#^Call to an undefined method object\:\:loadObject\(\)\.$#'
identifier: method.notFound
message: '#^Variable \$myAppCustomService might not be defined\.$#'
identifier: variable.undefined
count: 1
path: code_samples/_inline_php/infrastructure_and_maintenance/cache/persistence_cache/2f333548247830523074f882c44ffb2c58e158accf9fdcd50dcb4e2e86209b1f.php
path: code_samples/_inline_php/infrastructure_and_maintenance/cache/persistence_cache/c27a2fe1c12bba3e9271acc67ae3a2e2d4596bf58f4d9b791aec4e564ae88259.php

-
message: '#^Property App\\MyService\:\:\$contentService is never read, only written\.$#'
Expand Down
Loading