API d’existence & sessions exist Décidé
La question qui fait exister la dédup — « as-tu déjà ce chunk ? » — posée par liasses de 1 000, répondue par checklist. Et la subtilité qui fait tout : « présent » n'est pas une information, c'est une promesse à durée de session.
À quoi elle sert
Avant chaque envoi, le client demande à l’entrepôt lesquels de ses cartons existent déjà — et n’expédie que les manquants. C’est la question qui matérialise la dédup et la reprise après coupure. Un backup d’1 To en pose ~500 000, d’où le format industriel :
→ réponse : bitmap # 1 bit par adresse — 1 000 réponses = 125 octets
C’est aussi l’endroit où l’oracle de confirmation — accepté en principe côté crypto — devient un objet technique concret : la concevoir avec soin, c’est garantir qu’elle ne répond jamais plus que ce qu’on a décidé d’accepter.
Le piège mortel — la course avec l’équipe de ménage
La solution — le ticket de consigne
La mécanique complète :
- Ouverture — le backup commence par
POST /v1/sessions: un bracelet numéroté à l'entrée. Toutes les requêtes du run le référencent. - Épinglage — chaque réponse « présent » colle l'autocollant « réservé — déménagement n°42 en cours » sur le chunk. Les chunks fraîchement uploadés pendant le run — eux non plus réclamés par aucun inventaire — naissent avec le même autocollant. Un seul mécanisme protège les deux cas.
- Commit —
POST /v1/sessions/{id}/commitavec la racine du snapshot : les autocollants tombent, c'est désormais l'inventaire lui-même qui réclame les cartons. Atomique — la page d'album entre dans l'album entière, ou pas du tout. - Expiration — le run meurt en route ? Le bracelet expire (TTL), les autocollants tombent, les chunks redeviennent collectables — aucune fuite de réservations fantômes. À la reprise, le run suivant ouvre une nouvelle session, redemande « présent ? », re-colle les autocollants : la reprise par dédup fonctionne inchangée.
Deux notes d’architecture :
- Le client reste stateless — c'est le serveur qui tient la session, parfaitement dans le contrat : l'état vit chez le serveur, comme toujours.
- C'est LE point de contact avec le GC (l'autre nœud dur, section C) : en concevant l'API comme une promesse-à-durée-de-session, on donne au futur GC exactement la primitive dont il aura besoin — les époques protégées. Le problème difficile est simplifié avant d'être attaqué.
Le scoping tenant — défense en profondeur
Deux tenants ne peuvent même pas nommer les cartons l’un de l’autre (CK différentes → adresses jamais identiques, par construction). L’API ajoute quand même un second verrou : elle ne répond que pour l’espace de dédup du tenant authentifié. Si les adresses du tenant B fuient un jour par un autre canal (machine compromise, logs), un compte du tenant A ne peut pas s’en servir comme sonde. L’isolation existe dans la crypto et dans le protocole — deux verrous indépendants.
Le tic-tac de l’horloge
« Absent » est répondu par le portier à mémoire floue (bloom, RAM, instantané), « présent » exige d’ouvrir le registre (LSM) : les temps de réponse diffèrent. Fuite ? Seul le tenant interroge son propre espace, et le chrono ne lui apprend rien de plus que la réponse elle-même. Nulle dans notre modèle de menace. Le rate limiting (un client compromis qui sonde en masse) relève de la prévention d’abus, section I.
Et côté serveur — comment on répond vite ?
Ce n’est pas le sujet de cette page, et c’est voulu : le contrat (ce que l’API promet) vit ici, la mécanique (comment le serveur tient la promesse) est déjà gravée dans l’architecture du stockage. Rappel en une ligne : bloom filter en RAM (écarte instantanément les absents — la majorité pendant un backup de données neuves) → index LSM (réponse authoritaire, lookup ponctuel pur sur des clés uniformément aléatoires — le travail idéal d’un LSM) → et jamais, jamais de « présent » sur la foi du bloom seul.
En une phrase : l’API d’existence n’est pas un moteur de recherche, c’est un vestiaire — elle ne dit jamais « oui » sans tendre le ticket qui garantit que le manteau sera encore là au moment du retrait.