diff --git a/services/document-updater/app/coffee/UpdateManager.coffee b/services/document-updater/app/coffee/UpdateManager.coffee index 5064725aa0..56c0faa165 100644 --- a/services/document-updater/app/coffee/UpdateManager.coffee +++ b/services/document-updater/app/coffee/UpdateManager.coffee @@ -79,7 +79,7 @@ module.exports = UpdateManager = profile.log("sharejs.applyUpdate") return callback(error) if error? RangesManager.applyUpdate project_id, doc_id, ranges, appliedOps, updatedDocLines, (error, new_ranges) -> - UpdateManager._addProjectHistoryMetadataToOps(appliedOps, pathname, updatedDocLines) + UpdateManager._addProjectHistoryMetadataToOps(appliedOps, pathname, lines) profile.log("RangesManager.applyUpdate") return callback(error) if error? RedisManager.updateDocument project_id, doc_id, updatedDocLines, version, appliedOps, new_ranges, (error, doc_ops_length, project_ops_length) -> @@ -129,12 +129,26 @@ module.exports = UpdateManager = op.i = op.i.replace(/[\uD800-\uDFFF]/g, "\uFFFD") return update - _addProjectHistoryMetadataToOps: (ops, pathname, lines) -> + _addProjectHistoryMetadataToOps: (updates, pathname, lines) -> doc_length = _.reduce lines, (chars, line) -> chars + line.length, 0 doc_length += lines.length - 1 # count newline characters - ops.forEach (op) -> - op.meta ||= {} - op.meta.pathname = pathname - op.meta.doc_length = doc_length + updates.forEach (update) -> + update.meta ||= {} + update.meta.pathname = pathname + update.meta.doc_length = doc_length + # Each update may contain multiple ops, i.e. + # [{ + # ops: [{i: "foo", p: 4}, {d: "bar", p:8}] + # }, { + # ops: [{d: "baz", p: 40}, {i: "qux", p:8}] + # }] + # We want to include the doc_length at the start of each update, + # before it's ops are applied. However, we need to track any + # changes to it for the next update. + for op in update.op + if op.i? + doc_length += op.i.length + if op.d? + doc_length -= op.d.length diff --git a/services/document-updater/test/unit/coffee/UpdateManager/UpdateManagerTests.coffee b/services/document-updater/test/unit/coffee/UpdateManager/UpdateManagerTests.coffee index 946f5d9fbe..1d933bc5d4 100644 --- a/services/document-updater/test/unit/coffee/UpdateManager/UpdateManagerTests.coffee +++ b/services/document-updater/test/unit/coffee/UpdateManager/UpdateManagerTests.coffee @@ -245,20 +245,30 @@ describe "UpdateManager", -> 'test' 'data' ] - appliedOps = [ {v: 42, op: "mock-op-42"}, { v: 45, op: "mock-op-45" }] + appliedOps = [ + { v: 42, op: [{i: "foo", p: 4}, { i: "bar", p: 6 }] }, + { v: 45, op: [{d: "qux", p: 4}, { i: "bazbaz", p: 14 }] }, + { v: 49, op: [{i: "penguin", p: 18}] } + ] @UpdateManager._addProjectHistoryMetadataToOps(appliedOps, @pathname, lines) appliedOps.should.deep.equal [{ v: 42 - op: "mock-op-42" + op: [{i: "foo", p: 4}, { i: "bar", p: 6 }] meta: pathname: @pathname doc_length: 14 }, { v: 45 - op: "mock-op-45" + op: [{d: "qux", p: 4}, { i: "bazbaz", p: 14 }] meta: pathname: @pathname - doc_length: 14 + doc_length: 20 # 14 + 'foo' + 'bar' + }, { + v: 49 + op: [{i: "penguin", p: 18}] + meta: + pathname: @pathname + doc_length: 23 # 14 - 'qux' + 'bazbaz' }] describe "lockUpdatesAndDo", ->