Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

API upload & download blob Décidé

Le videur rehache chaque colis à la porte — l'empoisonnement est impossible par construction. Deux familles d'endpoints par classe de segment, un batch-get piloté par le serveur qui réalise « les courses par rayon », et le protocole de données est complet.

Upload — le videur à la porte

En clair — personne n'entre sous un faux nom À la réception de chaque colis (PUT /v1/chunks/{addr}), le serveur rehache le corps et vérifie BLAKE3(corps) == addr avant d'indexer. Mismatch = rejet sec. Conséquence énorme : l'empoisonnement est impossible par construction — on ne peut pas ranger un mauvais contenu sous une bonne adresse, puisque l'adresse est le hash du contenu. Une machine compromise du tenant peut uploader des déchets (un problème de quota), jamais corrompre un chunk que les autres machines dédupliquent.

Les propriétés :

  • Idempotent — re-uploader un chunk existant = succès no-op. Livrer deux fois le même carton n'est pas une erreur : c'est la reprise qui fonctionne.
  • Durable avant ack — le contrat de durabilité, appliqué au protocole.
  • Taille max ≈ 8 Mio + marge (le max du chunker) — au-delà, rejet.
  • Parallélisme par multiplexing H2, fenêtre en vol bornée côté client (pipeline).

Deux familles d’endpoints, par classe. Le serveur doit savoir dans quelle caisse ranger (segments données vs métadonnées) : /v1/chunks/* → segments données (HDD) ; /v1/meta/* (manifestes, répertoires, racines) → segments métadonnées (SSD). Les manifestes — convergents — ont leur check d’existence (POST /v1/meta/exists) ; les répertoires et racines, jamais (toujours neufs par construction). Même videur, mêmes règles partout.

Download — la liste de courses remise au magasinier

En clair — le picking dans l'ordre des rayons La restauration promettait « les courses par rayon » : télécharger les 500 000 chunks dans l'ordre des segments pour des lectures quasi séquentielles. Mais le client ne connaît pas les emplacements — seul l'index serveur sait que le colis b291 est dans la caisse 42. La réalisation propre : le client remet sa liste de courses (POST /v1/chunks/batch-get, tableau d'adresses), et le magasinier fait le picking dans l'ordre de ses rayons — le serveur streame les blobs dans son ordre optimal (trié segment/offset), en flux framé [addr | len | payload]. C'est lui qui connaît l'entrepôt.

Les GET unitaires (GET /v1/chunks/{addr}, GET /v1/meta/{addr}) restent pour la navigation, l’arbre parent du scan (petits nœuds, SSD, cachés en RAM) et le debug.

Le point d’entrée des racines. Le client stateless doit trouver la racine du snapshot parent : GET /v1/snapshots — la liste des refs, servie depuis la DB de contrôle (l’équivalent de git branch). C’est le seul endpoint qui touche la DB de contrôle sur le chemin des données ; tout le reste est du CAS pur.

Le protocole de données, complet

EndpointRôleParticularité
POST /v1/sessions · …/commitouvrir / committer un backupsession-promesse, commit atomique
POST /v1/chunks/exists · /v1/meta/existsdédup par lotsbitmap, épinglage à la session
PUT /v1/chunks/{addr} · /v1/meta/{addr}uploadrehash à la porte, idempotent, durable avant ack
POST /v1/chunks/batch-getrestaurationpicking par rayon, flux framé
GET /v1/chunks/{addr} · /v1/meta/{addr}lecture unitairenavigation, arbre parent, debug
GET /v1/snapshotsrefs des racinesseul contact avec la DB de contrôle
GET /v1/capabilitiesnégociationtailles de batch, features, versions (transport)

Sept familles d’endpoints : toute la surface dont l’agent a besoin pour sauvegarder et restaurer. Config, heartbeat et jobs s’y ajoutent (même style, polling) ; l’authentification est le sujet suivant. Et remarque ce qui n’existe pas : aucun endpoint de suppression — le client n’a pas la gomme.