Skip to content

Commit

Permalink
docs(api): ADR
Browse files Browse the repository at this point in the history
  • Loading branch information
laura-bergoens committed Dec 16, 2024
1 parent 4192e4b commit 362055d
Showing 1 changed file with 80 additions and 0 deletions.
80 changes: 80 additions & 0 deletions docs/adr/0058-modification-du-cache-du-contenu-pedagogique.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# 57. Modification du fonctionnement du cache de contenu pédagogique

Date : 2024-12-16

## État

Validée

## Historique

Pour ceux qui veulent toute l'histoire, voici le lien vers les précédentes ADR expliquant le fonctionnement du cache de contenu pédagogique aujourd'hui :

- [ADR de la mise en place du cache](0005-ajout-d-un-cache-memoire-distribute-pour-le-contenu-pedagogique.md)
- [ADR traitant du stockage en clé unique dans Redis et en mémoire vive](0016-stockage-du-referentiel-en-cache.md)

## Contexte

Le fonctionnement aujourd'hui consiste à stocker l'entièreté du contenu pédagogique en deux endroits :

- en mémoire vive
- sur Redis, de sorte que une machine qui vient de lancer un serveur récupère rapidement la donnée

### Limitations et problèmes

#### Crash mémoire

Le contenu pédagogique est un ensemble dont la taille grossit, doucement mais sûrement. Cela fait plusieurs semaines qu'on constate un dépassement mémoire sur les containers
lorsqu'ils traitent des opérations liées au cache de contenu pédagogique. Ces dépassements sont liés aux moments de lecture et d'écriture, depuis et vers le cache Redis.
Voici un extrait du fichier `RedisCache.js` :
```js
class RedisCache extends Cache {
// Lecture depuis le cache Redis
async get(key, generator) {
const value = await this._client.get(key);

if (value) {
const parsed = JSON.parse(value); // Dépassement mémoire ici
const patches = await this._client.lrange(`${key}:${PATCHES_KEY}`, 0, -1);
patches.map((patchJSON) => JSON.parse(patchJSON)).forEach((patch) => applyPatch(parsed, patch));
return parsed;
}

return this._manageValueNotFoundInCache(key, generator);
}
// Ecriture vers le cache Redis
async set(key, object) {
const objectAsString = JSON.stringify(object); // Dépassement mémoire ici

logger.info({ key, length: objectAsString.length }, 'Setting Redis key');

await this._client.set(key, objectAsString);
await this._client.del(`${key}:${PATCHES_KEY}`);

return object;
}
/* ... */
}
```
Redis stocke des chaînes de caractères, tandis qu'en mémoire vive nous conservons le contenu pédagogique en **_POJO_** (**_plain old javascript object_**). Cette conversion dans
les deux sens est donc faite dans le code (via `JSON.stringify` et `JSON.parse`), ce qui signifie qu'à un moment donné, dans la pile mémoire de traitement de la fonction,
on a simultanément le contenu pédagogique en **_POJO_** et en chaînes de caractères. Sachant que, ce jour, le contenu pédagogique fait environ 40 Mo, on peut estimer à, au
minimum, 80 Mo de données, sans parler des allocations diverses et variées nécessaires à l'exécution du code.

#### Peu optimisé
Le contenu pédagogique est stocké dans une seule clé. Cela pose deux défauts majeurs.

D'une part, nous n'avons pas le choix de ce qui mérite d'être promu dans le cache mémoire ou pas. Tout y est.
Pourtant, on sait qu'un certain nombre d'entités sont très peu ou pas consultés dans le fonctionnement des applications Pix, voici une liste non exhaustive :
- Les données sur des entités peu affichées (`frameworks` ou `thematics`)
- Les épreuves non jouables (car périmées ou en atelier)
- Les épreuves dans une langue encore peu jouée sur Pix


D'autre part, et on pense en particulier aux acquis et aux épreuves, il est fréquent de vouloir récupérer toujours le même sous-ensemble.
Par exemple, tous les utilisateurs qui se positionnent sur la même compétence, dans le code pour récupérer la prochaine épreuve,
on récupère les mêmes acquis et les mêmes épreuves juste avant de dérouler l'algorithme du choix d'épreuve. Aujourd'hui, on effectue donc les mêmes boucles et les mêmes filtres.


## Solution

0 comments on commit 362055d

Please sign in to comment.