Aller au contenu

Plan — Cache partagé des flux atlas via CloudNativePG

État : Achevé (2026-06-24) · Fonde : ADR 0093 (Accepted). Brique cluster livrée ET prouvée au banc (scénario 33 PASS). La part atlas (adaptateur Postgres derrière l’interface) est hors périmètre cluster → atlas#443.

Matérialise la brique cluster du cache partagé atlas (#150, épopée DataOps #223) : une base logique cache sur le CNPG existant + le contrat/DSN. L’adaptateur code derrière l’interface readCache/writeCache reste côté atlas (frontière, §5 ADR).

  • 0093 — la décision (Postgres, pas Redis ; advisory lock + UPSERT + table horodatée).
  • 0024 (CNPG, une base par usage) ; 0043 (contrat) ; 0023 (valeurs génériques).
  • Externe : ADR atlas 0040 (caches = backing service injectable).
  • Réutiliser CNPG : aucune nouvelle brique stateful. Base logique cache de plus sur le Cluster pg (comme dagster/pgvector/marquez/mlflow).
  • Frontière : le cluster fournit base + rôle + DSN. L’adaptateur Postgres derrière l’interface atlas (ATLAS_STATS_CACHE_PATH/CRF_LOGS_CACHE_PATH — aujourd’hui un PATH fichier) est atlas (issue atlas dédiée). Le cluster ne code pas le SQL.
  • Nomenclature : identifiant cache, jamais une marque (ADR 0043).
  • Banc local-path : preuve e2e sur le banc mono-nœud (plus de banc Ceph).
  • ÉDITER platform/cloudnative-pg/cluster.yaml : rôle managé cache dans spec.managed.roles avec passwordSecret: { name: pg-role-cache } (obligatoire — sans lui, rolpassword NULL, connexion impossible).
  • ÉDITER platform/cloudnative-pg/database.yaml : kind: Database name/owner: cache, cluster: pg.
  • ÉDITER platform/cloudnative-pg/role-secrets.example.yaml : Secret pg-role-cache (basic-auth, valeur de test au banc ; prod via config locale non versionnée).
  • Preuve : rejeu idempotent du rôle platform-cnpg (changed=0) ; base cache créée, connexion psql avec le rôle cache OK.
  • ÉDITER contract/endpoints.example.yaml : point de contact postgres-cache (service: pg-rw, namespace: postgres, port: 5432, auth: secret-role, base cache).
  • ÉDITER contract/namespaces-secrets.example.yaml : entrée pg-role-cache sous secrets.postgres_roles.items.
  • ÉDITER contract/atlas.env.cluster.example : bloc POSTGRES_CACHE_* dédié (ne PAS écraser les POSTGRES_* pgvector).
  • ÉDITER scripts/check_contract.py si l’ancrage du nouveau point de contact l’exige.
  • Preuve SANS cluster : check_contract + tests.
  • Scénario bench : 2 répliques d’un consommateur jouet partagent la base cache → vérifier (a) dédup (une seule ligne après actualisations concourantes), (b) bridage global (MIN_REFRESH_INTERVAL_MS respecté via la colonne horodatage + advisory lock), (c) pas de corruption sous écritures concurrentes (UPSERT atomique).
  • Preuve : le scénario PASS sur le banc banc.yaml (CNPG du banc).
  • Issue atlas : l’adaptateur Postgres derrière readCache/writeCache (la variable *_CACHE_PATH doit accepter un DSN postgres, pas qu’un chemin fichier). Hors ce dépôt.
  • Étape 1 — base/rôle cache (CNPG) : rôle managé + Database cache + Secret pg-role-cache (cluster.yaml / database.yaml / role-secrets.example.yaml)
  • Étape 2 — contrat : endpoint postgres-cache + secret pg-role-cache + bloc POSTGRES_CACHE_* (atlas.env) ; check_contract vert
  • Étape 3 — scénario banc 33-cache-cnpg.sh (connexion rôle cache + UPSERT atomique + pg_advisory_lock) + catalogue épreuves ; joué au banc le 2026-06-24 — PASS (STRICT_CACHE=1, exit 0)
  • Étape 4 — issue atlas (adaptateur Postgres derrière readCache/writeCache) : atlas#443