Cas d’usage
Sauvegarde continue
Un snapshot par compte, réécrit au fil des changements de la base locale, avec des écritures conditionnelles pour que deux appareils ne s’écrasent pas en silence.
const current = await store.getSnapshot(`user-${userId}`)
try {
await store.putSnapshot(`user-${userId}`, merged, { ifMatch: current?.etag })
} catch (error) {
if (isS3ndError(error) && error.code === 'PRECONDITION_FAILED') {
// Another device won. Read again, merge again.
}
throw error
}La situation
Ce qui se passe vraiment.
Le problème
Dès que l’app a des comptes, un code de transfert n’a plus la bonne forme. Il y a une session, donc le serveur sait déjà qui demande. Ce que l’utilisateur veut, c’est que ses données survivent à la perte du laptop, sans rien faire.
Ce que s3nd y fait
Indexez le snapshot par identifiant utilisateur plutôt que par code, et réécrivez-le à chaque changement de la base locale. Passez l’ETag lu en dernier comme ifMatch : un second appareil qui a écrit entre-temps fait échouer l’écriture avec PRECONDITION_FAILED au lieu de jeter silencieusement son travail, et votre app relit et fusionne.
À surveiller
Les choses faciles à rater.
Une règle de cycle de vie différente
Les sauvegardes ne doivent pas expirer. Gardez-les sous leur propre préfixe pour que la règle qui nettoie les transferts ne puisse pas les atteindre.
Temporiser les écritures
Un snapshot par frappe de touche, c’est une facture. Écrivez sur un minuteur, au changement de visibilité, et avant la fermeture.
La fusion vous appartient
s3nd vous dit que vous avez perdu la course. Décider ce qu’une fusion veut dire pour vos données est du code applicatif, et c’est pour ça que ce n’est pas caché.
Voir aussi
D’autres formes de la même primitive.
Déposez un fichier. Donnez le code.
Pointez-le sur le bucket que vous payez déjà. Rien à déployer, aucune inscription, personne au milieu.