Prechádzať zdrojové kódy

Flush track changes when unloading data from redis

James Allen 10 rokov pred
rodič
commit
af5d01e440

+ 8 - 5
services/document-updater/app/coffee/DocumentManager.coffee

@@ -4,6 +4,7 @@ DocOpsManager = require "./DocOpsManager"
 DiffCodec = require "./DiffCodec"
 DiffCodec = require "./DiffCodec"
 logger = require "logger-sharelatex"
 logger = require "logger-sharelatex"
 Metrics = require "./Metrics"
 Metrics = require "./Metrics"
+TrackChangesManager = require "./TrackChangesManager"
 
 
 module.exports = DocumentManager =
 module.exports = DocumentManager =
 	getDoc: (project_id, doc_id, _callback = (error, lines, version) ->) ->
 	getDoc: (project_id, doc_id, _callback = (error, lines, version) ->) ->
@@ -109,11 +110,13 @@ module.exports = DocumentManager =
 
 
 		DocumentManager.flushDocIfLoaded project_id, doc_id, (error) ->
 		DocumentManager.flushDocIfLoaded project_id, doc_id, (error) ->
 			return callback(error) if error?
 			return callback(error) if error?
-			# We should flush pending ops to track-changes here but this is
-			# already done in the real-time WebsocketController.leaveProject
-			# method so we leave it there.  Note, if you ever add the flush
-			# in here be sure to do it in the background because it can take
-			# a long time.
+			
+			# Flush in the background since it requires and http request
+			# to track changes
+			TrackChangesManager.flushDocChanges project_id, doc_id, (err) ->
+				if err?
+					logger.err {err, project_id, doc_id}, "error flushing to track changes"
+
 			RedisManager.removeDocFromMemory project_id, doc_id, (error) ->
 			RedisManager.removeDocFromMemory project_id, doc_id, (error) ->
 				return callback(error) if error?
 				return callback(error) if error?
 				callback null
 				callback null

+ 2 - 2
services/document-updater/test/acceptance/coffee/ApplyingUpdatesToADocTests.coffee

@@ -365,8 +365,8 @@ describe "Applying updates to a large doc (uses compression)", ->
 		after ->
 		after ->
 			MockTrackChangesApi.flushDoc.restore()
 			MockTrackChangesApi.flushDoc.restore()
 
 
-		it "should flush the doc twice", ->
-			MockTrackChangesApi.flushDoc.calledTwice.should.equal true
+		it "should flush the doc", ->
+			MockTrackChangesApi.flushDoc.called.should.equal true
 
 
 	describe "when there is no version in Mongo", ->
 	describe "when there is no version in Mongo", ->
 		before (done) ->
 		before (done) ->

+ 14 - 2
services/document-updater/test/acceptance/coffee/DeletingADocumentTests.coffee

@@ -3,6 +3,7 @@ chai = require("chai")
 chai.should()
 chai.should()
 {db, ObjectId} = require "../../../app/js/mongojs"
 {db, ObjectId} = require "../../../app/js/mongojs"
 
 
+MockTrackChangesApi = require "./helpers/MockTrackChangesApi"
 MockWebApi = require "./helpers/MockWebApi"
 MockWebApi = require "./helpers/MockWebApi"
 DocUpdaterClient = require "./helpers/DocUpdaterClient"
 DocUpdaterClient = require "./helpers/DocUpdaterClient"
 
 
@@ -18,6 +19,11 @@ describe "Deleting a document", ->
 			}]
 			}]
 			v: @version
 			v: @version
 		@result = ["one", "one and a half", "two", "three"]
 		@result = ["one", "one and a half", "two", "three"]
+		
+		sinon.spy MockTrackChangesApi, "flushDoc"
+	
+	after ->
+		MockTrackChangesApi.flushDoc.restore()
 
 
 	describe "when the updated doc exists in the doc updater", ->
 	describe "when the updated doc exists in the doc updater", ->
 		before (done) ->
 		before (done) ->
@@ -38,7 +44,7 @@ describe "Deleting a document", ->
 						setTimeout () =>
 						setTimeout () =>
 							DocUpdaterClient.deleteDoc @project_id, @doc_id, (error, res, body) =>
 							DocUpdaterClient.deleteDoc @project_id, @doc_id, (error, res, body) =>
 								@statusCode = res.statusCode
 								@statusCode = res.statusCode
-								done()
+								setTimeout done, 200
 						, 200
 						, 200
 
 
 		after ->
 		after ->
@@ -70,6 +76,9 @@ describe "Deleting a document", ->
 					.calledWith(@project_id, @doc_id)
 					.calledWith(@project_id, @doc_id)
 					.should.equal true
 					.should.equal true
 				done()
 				done()
+		
+		it "should flush track changes", ->
+			MockTrackChangesApi.flushDoc.calledWith(@doc_id).should.equal true
 
 
 	describe "when the doc is not in the doc updater", ->
 	describe "when the doc is not in the doc updater", ->
 		before (done) ->
 		before (done) ->
@@ -81,7 +90,7 @@ describe "Deleting a document", ->
 			sinon.spy MockWebApi, "getDocument"
 			sinon.spy MockWebApi, "getDocument"
 			DocUpdaterClient.deleteDoc @project_id, @doc_id, (error, res, body) =>
 			DocUpdaterClient.deleteDoc @project_id, @doc_id, (error, res, body) =>
 				@statusCode = res.statusCode
 				@statusCode = res.statusCode
-				done()
+				setTimeout done, 200
 
 
 		after ->
 		after ->
 			MockWebApi.setDocumentLines.restore()
 			MockWebApi.setDocumentLines.restore()
@@ -100,6 +109,9 @@ describe "Deleting a document", ->
 					.calledWith(@project_id, @doc_id)
 					.calledWith(@project_id, @doc_id)
 					.should.equal true
 					.should.equal true
 				done()
 				done()
+		
+		it "should flush track changes", ->
+			MockTrackChangesApi.flushDoc.calledWith(@doc_id).should.equal true
 
 
 		
 		
 
 

+ 10 - 0
services/document-updater/test/acceptance/coffee/DeletingAProjectTests.coffee

@@ -3,6 +3,7 @@ chai = require("chai")
 chai.should()
 chai.should()
 async = require "async"
 async = require "async"
 
 
+MockTrackChangesApi = require "./helpers/MockTrackChangesApi"
 MockWebApi = require "./helpers/MockWebApi"
 MockWebApi = require "./helpers/MockWebApi"
 DocUpdaterClient = require "./helpers/DocUpdaterClient"
 DocUpdaterClient = require "./helpers/DocUpdaterClient"
 
 
@@ -37,6 +38,11 @@ describe "Deleting a project", ->
 				lines: doc.lines
 				lines: doc.lines
 				version: doc.update.v
 				version: doc.update.v
 			}
 			}
+			
+		sinon.spy MockTrackChangesApi, "flushDoc"
+		
+	after ->
+		MockTrackChangesApi.flushDoc.restore()
 
 
 	describe "with documents which have been updated", ->
 	describe "with documents which have been updated", ->
 		before (done) ->
 		before (done) ->
@@ -78,5 +84,9 @@ describe "Deleting a project", ->
 			), () ->
 			), () ->
 				MockWebApi.getDocument.restore()
 				MockWebApi.getDocument.restore()
 				done()
 				done()
+		
+		it "should flush each doc in track changes", ->
+			for doc in @docs
+				MockTrackChangesApi.flushDoc.calledWith(doc.id).should.equal true
 
 
 
 

+ 3 - 3
services/document-updater/test/acceptance/coffee/SettingADocumentTests.coffee

@@ -86,7 +86,7 @@ describe "Setting a document", ->
 				throw error if error?
 				throw error if error?
 				DocUpdaterClient.setDocLines @project_id, @doc_id, @newLines, @source, @user_id, (error, res, body) =>
 				DocUpdaterClient.setDocLines @project_id, @doc_id, @newLines, @source, @user_id, (error, res, body) =>
 					@statusCode = res.statusCode
 					@statusCode = res.statusCode
-					done()
+					setTimeout done, 200
 		
 		
 		it "should return a 204 status code", ->
 		it "should return a 204 status code", ->
 			@statusCode.should.equal 204
 			@statusCode.should.equal 204
@@ -96,8 +96,8 @@ describe "Setting a document", ->
 				.calledWith(@project_id, @doc_id, @newLines)
 				.calledWith(@project_id, @doc_id, @newLines)
 				.should.equal true
 				.should.equal true
 		
 		
-		it "should flush track changes"#, ->
-			# MockTrackChangesApi.flushDoc.calledWith(@doc_id).should.equal true
+		it "should flush track changes", ->
+			MockTrackChangesApi.flushDoc.calledWith(@doc_id).should.equal true
 		
 		
 		it "should remove the document from redis", (done) ->
 		it "should remove the document from redis", (done) ->
 			rclient.get "doclines:#{@doc_id}", (error, lines) =>
 			rclient.get "doclines:#{@doc_id}", (error, lines) =>

+ 7 - 0
services/document-updater/test/unit/coffee/DocumentManager/flushAndDeleteDocTests.coffee

@@ -9,6 +9,7 @@ describe "DocumentUpdater - flushAndDeleteDoc", ->
 		@DocumentManager = SandboxedModule.require modulePath, requires:
 		@DocumentManager = SandboxedModule.require modulePath, requires:
 			"./RedisManager": @RedisManager = {}
 			"./RedisManager": @RedisManager = {}
 			"./PersistenceManager": @PersistenceManager = {}
 			"./PersistenceManager": @PersistenceManager = {}
+			"./TrackChangesManager": @TrackChangesManager = {}
 			"logger-sharelatex": @logger = {log: sinon.stub()}
 			"logger-sharelatex": @logger = {log: sinon.stub()}
 			"./DocOpsManager" :{}
 			"./DocOpsManager" :{}
 			"./Metrics": @Metrics =
 			"./Metrics": @Metrics =
@@ -22,6 +23,7 @@ describe "DocumentUpdater - flushAndDeleteDoc", ->
 		beforeEach ->
 		beforeEach ->
 			@RedisManager.removeDocFromMemory = sinon.stub().callsArg(2)
 			@RedisManager.removeDocFromMemory = sinon.stub().callsArg(2)
 			@DocumentManager.flushDocIfLoaded = sinon.stub().callsArgWith(2)
 			@DocumentManager.flushDocIfLoaded = sinon.stub().callsArgWith(2)
+			@TrackChangesManager.flushDocChanges = sinon.stub().callsArg(2)
 			@DocumentManager.flushAndDeleteDoc @project_id, @doc_id, @callback
 			@DocumentManager.flushAndDeleteDoc @project_id, @doc_id, @callback
 		
 		
 		it "should flush the doc", ->
 		it "should flush the doc", ->
@@ -39,3 +41,8 @@ describe "DocumentUpdater - flushAndDeleteDoc", ->
 
 
 		it "should time the execution", ->
 		it "should time the execution", ->
 			@Metrics.Timer::done.called.should.equal true
 			@Metrics.Timer::done.called.should.equal true
+		
+		it "should flush to track changes", ->
+			@TrackChangesManager.flushDocChanges
+				.calledWith(@project_id, @doc_id)
+				.should.equal true