Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fixed a weird replication scenario

  • Loading branch information...
commit 2da3a7aff8e0e4491c7659c58c549f42d9231ac5 1 parent 621ae49
@airportyh authored
View
53 browser-couch.js
@@ -780,16 +780,20 @@ var BrowserCouch = function(opts){
obj._rev = (revIndex(obj)+1) + '-' + revId;
}else if (orig && obj._rev != orig._rev){
function hasMatchingRev(rev, revisions){
- for (var i = 0; i < revisions.ids.length; i++){
- if (rev == (revisions.start - i) + '-' + revisions.ids[i])
- return true
- }
+ for (var i = 0; i < revisions.ids.length; i++){
+ if (rev == (revisions.start - i) + '-' + revisions.ids[i])
+ return true
+ }
return false
}
+ if (hasMatchingRev(obj._rev, docInfo.revisions)){
+ // If we already have this rev, do nothing
+ return
+ }
+
var revisions = obj._revisions
if (!revisions || !hasMatchingRev(orig._rev, revisions)){
-
var winner;
// use deterministic winner picking algorithm
if (revIndex(obj) > revIndex(orig))
@@ -807,7 +811,7 @@ var BrowserCouch = function(opts){
if (!docInfo._conflict_revisions)
docInfo._conflict_revisions = {}
docInfo._conflict_revisions[loser._rev] = loser
- }
+ }
}
}
if (!orig && !obj._deleted){
@@ -1075,11 +1079,17 @@ var BrowserCouch = function(opts){
var source = 'BrowserCouch:' + dbName
var couch = new Couch({url: target})
//console.log('bulkDocs: ' + JSON.stringify(bulkDocs));
-
+ cb = cb ? (function(){
+ var oldCb = cb
+ return function(repInfo, status){
+ endRemoteSync()
+ oldCb.call(this, repInfo, status)
+ }
+ })() : endRemoteSync
var repInfoID = this.upRepInfoID(couch.baseUrl)
couch.get(repInfoID, null, function(repInfo, status){
if (!status){
- if (cb) cb.call(context, repInfo, status)
+ cb.call(context, repInfo, status)
return
}
if (repInfo.error){
@@ -1092,27 +1102,26 @@ var BrowserCouch = function(opts){
var since = repInfo.source_last_seq
var changes = this.getChanges({since: since});
if (changes.results.length == 0){
- if (cb) cb.call(context, repInfo, status)
+ cb.call(context, repInfo, status)
return
}
var bulkDocs = this.createBulkDocs(changes);
couch.post('_bulk_docs', bulkDocs, function(reply, status){
if (!reply || reply.error){
- if (cb) cb.call(context, reply, status)
+ cb.call(context, reply, status)
return
}
couch.post('_ensure_full_commit', 'true', function(reply, status){
//console.log('_ensure_full_commit: ' + status)
if (!reply || reply.error){
- if (cb) cb.call(context, reply, status)
+ cb.call(context, reply, status)
return
}
repInfo.source_last_seq = self.lastSeq()
couch.put(repInfoID, repInfo, function(reply, status){
//console.log(repInfoID + ': ' + status)
- endRemoteSync()
if (reply.ok)
- if (cb) cb.call(context, reply, status)
+ cb.call(context, reply, status)
})
}, this)
}, this)
@@ -1122,6 +1131,14 @@ var BrowserCouch = function(opts){
self.syncFromRemote = function BC_syncFromRemote(source, cb, context){
initRemoteSync()
var self = this;
+
+ cb = cb ? (function(){
+ var oldCb = cb
+ return function(repInfo, status){
+ endRemoteSync()
+ oldCb.call(this, repInfo, status)
+ }
+ })() : endRemoteSync
var target = 'BrowserCouch:' + dbName;
var couch = new Couch({url: source});
@@ -1131,17 +1148,17 @@ var BrowserCouch = function(opts){
repInfo.source_last_seq = changes.last_seq
couch.put(repInfoID, repInfo, function(reply, status){
endRemoteSync()
- if (cb) cb.call(context, changes, status)
+ cb.call(context, changes, status)
})
}
function fastMerge(repInfo){
couch.get('_changes', {
include_docs: true,
- since: since
+ since: 0
}, function(changes, status){
if (!changes || changes.error){
- if (cb) cb.call(context, changes, status)
+ cb.call(context, changes, status)
return
}
changes.results.forEach(function(change){
@@ -1154,7 +1171,7 @@ var BrowserCouch = function(opts){
function slowMerge(since, repInfo){
couch.get('_changes', {since: since}, function(changes, status){
if (!changes || changes.error){
- if (cb) cb.call(context, changes, status)
+ cb.call(context, changes, status)
return
}
@@ -1185,7 +1202,7 @@ var BrowserCouch = function(opts){
couch.get(repInfoID, null, function(repInfo, status){
if (!repInfo){
- if (cb) cb.call(context, repInfo, status)
+ cb.call(context, repInfo, status)
return
}
if (repInfo.error){
View
17 html/js/spec/replication_scenarios.js
@@ -0,0 +1,17 @@
+describe('Replication Scenarios')
+ .should('weird scenario which shouldnt cause conflict', function(){
+ var db1 = BrowserCouch('db1')
+ db1.wipe()
+ var db2 = BrowserCouch('db2')
+ db2.wipe()
+ db1.put({_id: '1', name: 'Ken'})
+ db1.syncToLocal(db2)
+ var ken = db1.get('1')
+ ken.name = 'Kennedy'
+ db1.put(ken)
+ db2.syncToLocal(db1)
+ var kenP = db1.get('1')
+ expect(kenP._conflicts).toBe(undefined)
+ db1.wipe()
+ db2.wipe()
+ })
View
4 html/js/spec/replication_up.js
@@ -159,10 +159,12 @@ describe('BrowserCouch Replicate Up', {async: true})
.should('prevent doing more than one remote sync at a time', function(){
var self = this
self.db.syncToRemote(self.couch.baseUrl, function(reply, status){
+ self.db.syncToRemote(self.couch.baseUrl, function(reply, status){
+ self.finish()
+ })
})
expect(function(){
self.db.syncToRemote(self.couch.baseUrl, function(reply, status){})
}).toRaise("Tried to sync remotely while another sync is in progress.")
- self.finish()
})
View
1  html/js/spec/spec.html
@@ -16,6 +16,7 @@
<script src="replication_down.js"></script>
<script src="replication_local.js"></script>
+ <script src="replication_scenarios.js"></script>
<script src="sync_api.js"></script>
<script src="conflict_management_local.js"></script>
Please sign in to comment.
Something went wrong with that request. Please try again.