openxtrem/cache

OpenXtrem Cache

5.0.3 2025-03-03 09:56 UTC

README

Implémentation PSR-16 d'un cache chaîné (généralement nommé Chain Cache).

Ce cache permet de déléguer les appels à d'autres adaptateurs PSR-16 et vise à fournir une grande souplesse dans la maîtrise des performances (par rapport à l'accessibilité de l'item recherché).

Couches

Cet adaptateur utilise trois notions de couches différentes, à savoir :

  • INNER : Représente la couche dite intra-requête, c'est-à-dire qu'un item présent au sein de cette couche ne sera pas persisté entre deux requêtes HTTP (celui-ci expirera à la fin de la première). C'est un cache dit statique et très performant.
  • OUTER : Représente la couche dite inter-requête ou intra-serveur, où un item sera persisté entre deux requêtes. À noter qu'un item présent au sein de cette couche n'est censé persister qu'au sein d'un seul serveur. C'est l'usage traditionnel d'un cache (exemples : RAM, système de fichiers, etc.)
  • DISTR : Représente la couche dite inter-serveur, où un item est persisté entre plusieurs requêtes et plusieurs serveurs. C'est un cache dit distribué et c'est aussi généralement le plus lent du fait d'appels réseaux (exemples : Redis, Memcache, etc.)

Ainsi, lorsque LayeredCache est utilisé, par exemple avec la méthode LayeredCache::get, l'adaptateur va d'abord chercher l'item dans sa couche INNER, puis, si celui-ci n'existe pas, dans la couche OUTER, et ainsi de suite.

L'intérêt de cette approche est que lorsque l'item est retrouvé, par exemple au sein de la couche DISTR, alors LayeredCache va utiliser la méthode LayeredCache::set pour valuer l'item au sein des couches dites inférieures (ici, OUTER puis INNER) afin d'optimiser les appels futurs.

Initialisation

L'initialisation se fait comme suit :

<?php

use Ox\Components\Cache\Adapters\APCuAdapter;
use Ox\Components\Cache\Adapters\ArrayAdapter;
use Ox\Components\Cache\Adapters\PredisAdapter;
use Ox\Components\Cache\LayeredCache;
use Predis\Client;

LayeredCache::init('namespace')
    ->setAdapter(LayeredCache::INNER, new ArrayAdapter())
    ->setAdapter(LayeredCache::OUTER, new APCuAdapter())
    ->setAdapter(LayeredCache::DISTR, new PredisAdapter(new Client()));

Un namespace est nécessaire pour éviter les conflits de nommage éventuels (par exemple sur un serveur mutualisé).

Les trois adaptateurs PSR-16 sont fournis à LayeredCache, avec chacun leur couche relative. Du plus performant au plus "persistant" :

  • INNER, un cache statique PHP ;
  • OUTER, un cache mémoire APCu ;
  • DISTR, un cache distribué Redis.

Récupération d'une instance de LayeredCache

Combinaison de couches

L'intérêt d'un tel système réside dans le fait qu'il est possible de préalablement sélectionner les couches désirées pour son cache.

Les couches sont représentées par des constantes de la classe LayeredCache et doivent être fournies lors de la récupération d'une instance de cache.

Ainsi, l'initialisation d'une instance de LayeredCache, avec uniquement les couches INNER et OUTER se fait comme suit :

<?php

use Ox\Components\Cache\LayeredCache;

$cache = LayeredCache::getCache(LayeredCache::INNER | LayeredCache::OUTER);

Ou plus simplement :

<?php

use Ox\Components\Cache\LayeredCache;

$cache = LayeredCache::getCache(LayeredCache::INNER_OUTER);

Avec compression

Un décorateur permettant la compression des données mises en cache est également fourni nativement.

Lorsque l'adaptateur récupére le contenu d'un item, celui-ci est automatiquement décompressé (si cela est nécessaire), indépendemment du fait que le compresseur ait été activé ou non.

Pour initialiser la compression lors de l'affectation d'une valeur à un item :

<?php

use Ox\Components\Cache\LayeredCache;

$cache = LayeredCache::getCache(LayeredCache::INNER_OUTER)->withCompressor();

Ainsi, les valeurs affectées à l'aide des méthodes LayeredCache::set et LayeredCache::setMultiple seront compressées.

Affectation de metadonnées

Des metadonnées relatives à chaque adaptateur peuvent être insérées lors de l'initialisation.

<?php

use Ox\Components\Cache\Adapters\APCuAdapter;
use Ox\Components\Cache\Adapters\ArrayAdapter;
use Ox\Components\Cache\Adapters\PredisAdapter;
use Ox\Components\Cache\LayeredCache;
use Predis\Client;

LayeredCache::init('namespace')
            ->setAdapter(LayeredCache::INNER, new ArrayAdapter(),              ['namespaced' => false, 'engine' => 'PHP Array', 'engine_version' => 'N/A'])
            ->setAdapter(LayeredCache::OUTER, new APCuAdapter(),               ['namespaced' => false, 'engine' => 'APCu',      'engine_version' =  phpversion('apcu')])
            ->setAdapter(LayeredCache::DISTR, new PredisAdapter(new Client()), ['namespaced' => false, 'engine' => 'Redis',     'engine_version' =  '6.2']);

Celles-ci sont récupérables depuis la méthode :

<?php

use Ox\Components\Cache\LayeredCache;

$cache    = LayeredCache::getCache(LayeredCache::NONE);
$metadata = $cache->getMetadata();

Seule la metadonnée namespaced est utilisée en interne (par défaut à false) afin d'indiquer à LayeredCache si l'un des adaptateurs qu'il utilise est autonome à ce sujet.

Adaptateurs fournis par défaut

Les adaptateurs suivants sont proposés :

  • NullAdapter : Ne fait rien, à utiliser à des fins de test.
  • ArrayAdapter : Adaptateur utilisant un tableau PHP statique, très performant, pour du cache INNER.
  • FileAdapter : Enregistre les items de cache dans des fichiers au sein d'un répertoire donné.
  • APCuAdapter : Utilise le très performant APCu.
  • PredisAdapter : Utilise le client Predis, pour du cache distribué.