2014-06-23 4 views
0

Je souhaite pouvoir empêcher une 'poussée' (ou réplication) vers l'instance centrale de CouchDB à partir de l'instance locale d'un utilisateur (où il y a beaucoup d'utilisateurs) s'il y a des conflits - en copiant essentiellement la fonctionnalité à partir de quelque chose comme Git ou Mercurial, où les utilisateurs doivent résoudre les conflits sur leur copie locale avant de pousser sur le serveur central (de sorte que le serveur peut rester «propre»). D'après ce que je peux voir, il y a deux options:CouchDB empêche la réplication en cas de conflit

empêcher un utilisateur de valider s'il y a des conflits (bien que je ne vois aucun moyen de le faire sans terminer la réplication), ou terminer la réplication, voir s'il y a des conflits, puis supprimer la réplication poussée (et les documents) s'il y a des conflits (bien que cela puisse également entraîner un comportement indésirable si un retrait est effectué avant que les documents ne soient à nouveau supprimés, en plus d'être un peu inefficace). Donc, pour réduire cela, idéalement, Je voudrais une réplication pour revenir en arrière s'il y a un conflit, et pour m'informer qu'un conflit s'est produit (Je me fiche de la nature du conflit, parce que je peux alors lancer une réplication de demande de traction pour répliquer la base de données centrale sur la base de données locale).

Y a-t-il un moyen de réaliser l'une ou l'autre approche que j'ai manquée?

Répondre

0

Bien que ce ne soit pas la meilleure solution, j'ai fait quelque chose de plus compliqué;

  1. Émettez une requête de pull de réplication vers la base de données centrale, en spécifiant l'ID de réplication en tant que [RequestingMacAddress]. [Guid].
  2. Lors de l'envoi d'une requête push de réplication à la base de données centrale, je vérifie le dernier ID de demande de pull (sur la base de données centrale), en utilisant une vue personnalisée (utilisant la même adresse MAC).
  3. Je tire les _changes dans l'ordre décroissant, et m'assure que les changements les plus récents sur la base de données étaient soit [RequestingMacAddress]. [GUID] spécifié ci-dessus, soit une autre requête pull (sur un autre ordinateur) et aucune tâche sont actuellement actives (par exemple, une réplication push est en cours depuis une autre machine).
  4. Si tout est bon - permettre à la réplication push de continuer, sinon une erreur survient.

Recherche de meilleures solutions si disponibles.

0

Vous pouvez essayer d'y parvenir en utilisant une fonction validate_doc_update. AFAIK vous pouvez accéder à la propriété _conflicts dans le nouveau document pour vérifier s'il y aurait des conflits. Mais je n'ai jamais essayé ça auparavant.

Peut-être une fonction comme cela fonctionnerait:

function(newDoc, oldDoc, userCtx, secObj) { 
    if (newDoc._conflicts && newDoc._conflicts.length) { 
    throw({forbidden: 'Your change would cause conflicts. Try resolving the conflicts locally before replicating.'}); 
    } 
} 

Assurez-vous que cette fonction validate_doc_update existe que dans une conception doc sur la base de données centrale, car sinon les utilisateurs ne seraient pas en mesure de conflit « tirer » changements à leurs bases de données locales.

Faites-moi savoir si cela fonctionne!

+0

Merci Bernhard, je vais essayer et revenir vers vous. L'autre option sur laquelle je travaille est de comparer checkpoint_seq de la réplication pull la plus récente par cette machine (en utilisant le MAC de la machine dans l'ID de réplication), puis en vérifiant _changes pour identifier s'il y a eu des changements ultérieurs. Votre solution est plus jolie cependant, si cela fonctionne! – Ian

+1

D'après ce que j'ai vu - j'ai appelé les clés (newDoc) et connecté les propriétés de l'objet - semble qu'il a seulement _id, _rev et _revisions malheureusement. Je suppose que s'il est supprimé, il peut obtenir la propriété supplémentaire _deleted comme indiqué par les docs. – Ian

+0

Merci pour l'info, dommage que cela ne fonctionne pas ... –

Questions connexes