Existe-t-il une bibliothèque ou un outil standard pour calculer et appliquer des différences aux documents JSON ? En gros, j'ai un tas de documents volumineux que je veux garder synchronisés sur un réseau, et je préférerais éviter d'avoir à renvoyer leur état complet chaque fois que je veux les synchroniser (puisque beaucoup de ces variables ne vont pas changer). En d'autres termes, je ne veux transmettre que les champs qui ont changé, et non pas retransmettre l'objet entier. Je pense qu'il serait pratique d'avoir quelque chose comme l'ensemble de méthodes suivant :
//Start with two distinct objects on the server
// prev represents a copy of the state of the object on the client
// next represents a copy of the state of the object on the server
//
//1. Compute a patch
patch = computePatch(prev, next);
//2. Send patch over the network
//3. Apply the patch on the client
applyPatch(prev, patch);
//Final invariant:
// prev represents an equivalent object to JSON.parse(JSON.stringify(next))
Je pourrais certainement en implémenter un moi-même, mais il y a pas mal de cas limites à prendre en compte. Voici quelques-unes des méthodes simples (bien qu'un peu insatisfaisantes) auxquelles je peux penser :
-
Mettre en place mon propre correcteur JSON. Asymptotiquement, c'est probablement la meilleure façon de procéder, puisqu'il serait possible de supporter toutes les caractéristiques pertinentes des documents JSON, tout en supportant quelques méthodes spécialisées pour faire des choses comme différencier les ints, les doubles et les chaînes (en utilisant l'encodage relatif/la distance d'édition). Cependant, JSON a beaucoup de cas spéciaux et je suis un peu méfiant à l'idée d'essayer de faire cela sans beaucoup de tests, et donc je préférerais de loin trouver quelque chose qui résout déjà ce problème pour moi afin que je puisse lui faire confiance, et ne pas avoir à m'inquiéter de l'apparition de Heisenbugs réseau à cause d'erreurs dans mon JSON Parcheando.
-
Il suffit de calculer la distance d'édition directement entre les chaînes JSON en utilisant la programmation dynamique. Malheureusement, cela ne fonctionne pas si le client et le serveur ont des implémentations JSON différentes (c'est-à-dire que l'ordre de leurs champs pourrait être sérialisé différemment), et c'est également assez coûteux, étant une opération en temps quadratique.
-
Utilisez des tampons de protocole. Les tampons de protocole ont une méthode diff intégrée qui fait exactement ce que je veux, et ils constituent un format binaire sérialisable convivial pour le réseau. Malheureusement, parce qu'ils sont aussi strictement typés, ils n'ont pas les nombreux avantages de l'utilisation de JSON, comme la possibilité d'ajouter et de supprimer dynamiquement des champs. C'est l'approche vers laquelle je me tourne actuellement, mais elle pourrait rendre la maintenance future vraiment horrible, car je devrais continuellement mettre à jour chacun de mes objets.
-
Faire quelque chose de vraiment désagréable, comme créer un protocole personnalisé pour chaque type d'objet, et espérer que j'ai raison aux deux endroits (ouais, c'est ça !).
Bien sûr, ce que j'espère vraiment, c'est que quelqu'un ici, sur stackoverflow, vienne me sauver la mise en me donnant la référence d'un différentiateur/patcheur d'objets en javascript efficace et bien testé dans des environnements de production et sur plusieurs navigateurs.
* Mise à jour *
J'ai commencé à écrire mon propre patcheur, une première version est disponible sur github ici :
https://github.com/mikolalysenko/patcher.js
Comme il ne semble pas y avoir grand-chose, je vais plutôt accepter comme réponse alternative une liste de cas de test intéressants pour un correcteur JSON.
0 votes
Puisque vous avez mentionné "un certain nombre de cas limites qui doivent être pris en compte", il serait utile (pour votre réponse et pour la postérité) que vous énumériez les cas limites qui doivent être traités et comment ils doivent être résolus.
0 votes
Par ailleurs, la deuxième partie de votre question est intéressante pour montrer que vous avez réfléchi au problème, et pourrait être intéressante dans le cadre d'une réponse de type "solutions de rechange", mais elle n'a rien à voir avec la question, n'est-ce pas ?
0 votes
Il est toujours possible d'ajouter un
dirty
drapeau.1 votes
Il y a un
dirty
drapeau ? Je ne le vois pas.0 votes
La définition de "gros" a de l'importance, et la façon dont ils changent a de l'importance. À moins que vous n'ayez d'énormes documents qui subissent en permanence un très grand nombre de petites modifications, cette optimisation pourrait être prématurée.
0 votes
@user237815 : Renvoyer les documents sur le réseau pour chaque mise à jour est hors de question pour le moment. Le coût en bande passante supplémentaire et en latence serait beaucoup trop important.
0 votes
David Wick : J'ai pensé à cela aussi, et je suppose que je devrais ajouter que j'ai essayé au début mais que c'est devenu assez ennuyeux de garder une trace. J'ai eu cette idée pour contourner le problème, mais il existe peut-être de meilleures solutions.
0 votes
Cette question de l'OS a une discussion similaire stackoverflow.com/questions/584338/
0 votes
Google drive API fait exactement cela en JS mais ce n'est probablement pas ce que vous recherchez.