Просмотр исходного кода

Merge pull request #14 from sharelatex/ja-calculate-doclength

Calculate and send doc length before each update
Brian Gough 8 лет назад
Родитель
Сommit
e3efbaffac

+ 20 - 6
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

+ 14 - 4
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", ->