From dc2dfaa66c2c0bcb84cd4febeef29d3d2ce78771 Mon Sep 17 00:00:00 2001 From: James Allen Date: Sat, 22 Mar 2014 09:34:32 +0000 Subject: [PATCH] Flush project to track changes when leaving --- .../Features/Editor/EditorController.coffee | 2 + .../TrackChanges/TrackChangesManager.coffee | 16 +++++++ .../Editor/EditorControllerTests.coffee | 9 +++- .../TrackChangesManagerTests.coffee | 48 +++++++++++++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 services/web/app/coffee/Features/TrackChanges/TrackChangesManager.coffee create mode 100644 services/web/test/UnitTests/coffee/TrackChanges/TrackChangesManagerTests.coffee diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index fce0e68365..c3cf4b6ac0 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -13,6 +13,7 @@ AuthorizationManager = require("../Security/AuthorizationManager") AutomaticSnapshotManager = require("../Versioning/AutomaticSnapshotManager") VersioningApiHandler = require("../Versioning/VersioningApiHandler") EditorRealTimeController = require("./EditorRealTimeController") +TrackChangesManager = require("../TrackChanges/TrackChangesManager") settings = require('settings-sharelatex') slReqIdHelper = require('soa-req-id') tpdsPollingBackgroundTasks = require('../ThirdPartyDataStore/TpdsPollingBackgroundTasks') @@ -104,6 +105,7 @@ module.exports = EditorController = logger.log project_id: project_id, connectedCount: peopleStillInProject, "flushing if empty" if peopleStillInProject == 0 DocumentUpdaterHandler.flushProjectToMongoAndDelete(project_id) + TrackChangesManager.flushProject(project_id) callback() ), 500 diff --git a/services/web/app/coffee/Features/TrackChanges/TrackChangesManager.coffee b/services/web/app/coffee/Features/TrackChanges/TrackChangesManager.coffee new file mode 100644 index 0000000000..49fa956cf6 --- /dev/null +++ b/services/web/app/coffee/Features/TrackChanges/TrackChangesManager.coffee @@ -0,0 +1,16 @@ +settings = require "settings-sharelatex" +request = require "request" +logger = require "logger-sharelatex" + +module.exports = TrackChangesManager = + flushProject: (project_id, callback = (error) ->) -> + logger.log project_id: project_id, "flushing project in track-changes api" + url = "#{settings.apis.trackchanges.url}/project/#{project_id}/flush" + request.post url, (error, res, body) -> + return callback(error) if error? + if 200 <= res.statusCode < 300 + callback(null) + else + error = new Error("track-changes api responded with non-success code: #{res.statusCode}") + logger.error err: error, project_id: project_id, "error flushing project in track-changes api" + callback(error) \ No newline at end of file diff --git a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee index 3a0eb1120b..933c5bae3b 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee @@ -70,6 +70,7 @@ describe "EditorController", -> '../ThirdPartyDataStore/TpdsPollingBackgroundTasks':@TpdsPollingBackgroundTasks './EditorRealTimeController':@EditorRealTimeController = {} "../../infrastructure/Metrics": @Metrics = { inc: sinon.stub() } + "../TrackChanges/TrackChangesManager": @TrackChangesManager = {} 'redis':createClient:-> auth:-> "logger-sharelatex": @logger = log: sinon.stub() @@ -219,20 +220,24 @@ describe "EditorController", -> .should.equal true describe "flushProjectIfEmpty", -> + beforeEach -> + @DocumentUpdaterHandler.flushProjectToMongoAndDelete = sinon.stub() + @TrackChangesManager.flushProject = sinon.stub() + describe "when a project has no more users", -> it "should do the flush after the config set timeout to ensure that a reconect didn't just happen", (done)-> @rooms[@project_id] = [] - @DocumentUpdaterHandler.flushProjectToMongoAndDelete = sinon.stub() @EditorController.flushProjectIfEmpty @project_id, => @DocumentUpdaterHandler.flushProjectToMongoAndDelete.calledWith(@project_id).should.equal(true) + @TrackChangesManager.flushProject.calledWith(@project_id).should.equal true done() describe "when a project still has connected users", -> it "should not flush the project", (done)-> @rooms[@project_id] = ["socket-id-1", "socket-id-2"] - @DocumentUpdaterHandler.flushProjectToMongoAndDelete = sinon.stub() @EditorController.flushProjectIfEmpty @project_id, => @DocumentUpdaterHandler.flushProjectToMongoAndDelete.calledWith(@project_id).should.equal(false) + @TrackChangesManager.flushProject.calledWith(@project_id).should.equal false done() describe "updateClientPosition", -> diff --git a/services/web/test/UnitTests/coffee/TrackChanges/TrackChangesManagerTests.coffee b/services/web/test/UnitTests/coffee/TrackChanges/TrackChangesManagerTests.coffee new file mode 100644 index 0000000000..7dad07e48b --- /dev/null +++ b/services/web/test/UnitTests/coffee/TrackChanges/TrackChangesManagerTests.coffee @@ -0,0 +1,48 @@ +chai = require('chai') +chai.should() +sinon = require("sinon") +modulePath = "../../../../app/js/Features/TrackChanges/TrackChangesManager" +SandboxedModule = require('sandboxed-module') + +describe "TrackChangesManager", -> + beforeEach -> + @TrackChangesManager = SandboxedModule.require modulePath, requires: + "request" : @request = sinon.stub() + "settings-sharelatex": @settings = + apis: + trackchanges: + url: "trackchanges.sharelatex.com" + "logger-sharelatex": @logger = {log: sinon.stub(), error: sinon.stub()} + @project_id = "project-id-123" + @callback = sinon.stub() + + describe "flushProject", -> + describe "with a successful response code", -> + beforeEach -> + @request.post = sinon.stub().callsArgWith(1, null, statusCode: 204, "") + @TrackChangesManager.flushProject @project_id, @callback + + it "should flush the project in the track changes api", -> + @request.post + .calledWith("#{@settings.apis.trackchanges.url}/project/#{@project_id}/flush") + .should.equal true + + it "should call the callback without an error", -> + @callback.calledWith(null).should.equal true + + describe "with a failed response code", -> + beforeEach -> + @request.post = sinon.stub().callsArgWith(1, null, statusCode: 500, "") + @TrackChangesManager.flushProject @project_id, @callback + + it "should call the callback with an error", -> + @callback.calledWith(new Error("track-changes api responded with a non-success code: 500")).should.equal true + + it "should log the error", -> + @logger.error + .calledWith({ + err: new Error("track-changes api responded with a non-success code: 500") + project_id: @project_id + }, "error flushing project in track-changes api") + .should.equal true +