Merge pull request #84 from overleaf/bg-skip-history-flush-on-realtime-shutdown

skip history flush when project is cleared by realtime shutdown
This commit is contained in:
Brian Gough 2019-08-15 11:06:15 +01:00 committed by GitHub
commit a9ba7937c5
6 changed files with 84 additions and 5 deletions

View file

@ -28,6 +28,9 @@ module.exports = HistoryManager =
# flush changes and callback (for when we need to know the queue is flushed)
flushProjectChanges: (project_id, options, callback = (error) ->) ->
return callback() if !Settings.apis?.project_history?.enabled
if options.skip_history_flush
logger.log {project_id}, "skipping flush of project history from realtime shutdown"
return callback()
url = "#{Settings.apis.project_history.url}/project/#{project_id}/flush"
qs = {}
qs.background = true if options.background # pass on the background flush option if present

View file

@ -133,6 +133,7 @@ module.exports = HttpController =
timer = new Metrics.Timer("http.deleteProject")
options = {}
options.background = true if req.query?.background # allow non-urgent flushes to be queued
options.skip_history_flush = true if req.query?.shutdown # don't flush history when realtime shuts down
ProjectManager.flushAndDeleteProjectWithLocks project_id, options, (error) ->
timer.done()
return next(error) if error?

View file

@ -41,17 +41,15 @@ describe "Deleting a project", ->
version: doc.update.v
}
sinon.spy MockTrackChangesApi, "flushDoc"
sinon.spy MockProjectHistoryApi, "flushProject"
DocUpdaterApp.ensureRunning(done)
after ->
MockTrackChangesApi.flushDoc.restore()
MockProjectHistoryApi.flushProject.restore()
describe "with documents which have been updated", ->
before (done) ->
sinon.spy MockWebApi, "setDocument"
sinon.spy MockTrackChangesApi, "flushDoc"
sinon.spy MockProjectHistoryApi, "flushProject"
async.series @docs.map((doc) =>
(callback) =>
DocUpdaterClient.preloadDoc @project_id, doc.id, (error) =>
@ -68,6 +66,8 @@ describe "Deleting a project", ->
after ->
MockWebApi.setDocument.restore()
MockTrackChangesApi.flushDoc.restore()
MockProjectHistoryApi.flushProject.restore()
it "should return a 204 status code", ->
@statusCode.should.equal 204
@ -96,3 +96,42 @@ describe "Deleting a project", ->
it "should flush each doc in project history", ->
MockProjectHistoryApi.flushProject.calledWith(@project_id).should.equal true
describe "with the shutdown=true parameter from realtime", ->
before (done) ->
sinon.spy MockWebApi, "setDocument"
sinon.spy MockTrackChangesApi, "flushDoc"
sinon.spy MockProjectHistoryApi, "flushProject"
async.series @docs.map((doc) =>
(callback) =>
DocUpdaterClient.preloadDoc @project_id, doc.id, callback
), (error) =>
throw error if error?
setTimeout () =>
DocUpdaterClient.deleteProjectOnShutdown @project_id, (error, res, body) =>
@statusCode = res.statusCode
done()
, 200
after ->
MockWebApi.setDocument.restore()
MockTrackChangesApi.flushDoc.restore()
MockProjectHistoryApi.flushProject.restore()
it "should return a 204 status code", ->
@statusCode.should.equal 204
it "should send each document to the web api", ->
for doc in @docs
MockWebApi.setDocument
.calledWith(@project_id, doc.id, doc.updatedLines)
.should.equal true
it "should flush each doc in track changes", ->
for doc in @docs
MockTrackChangesApi.flushDoc.calledWith(doc.id).should.equal true
it "should not flush to project history", ->
MockProjectHistoryApi.flushProject.called.should.equal false

View file

@ -75,6 +75,9 @@ module.exports = DocUpdaterClient =
deleteProject: (project_id, callback = () ->) ->
request.del "http://localhost:3003/project/#{project_id}", callback
deleteProjectOnShutdown: (project_id, callback = () ->) ->
request.del "http://localhost:3003/project/#{project_id}?background=true&shutdown=true", callback
acceptChange: (project_id, doc_id, change_id, callback = () ->) ->
request.post "http://localhost:3003/project/#{project_id}/doc/#{doc_id}/change/#{change_id}/accept", callback

View file

@ -46,6 +46,28 @@ describe "HistoryManager", ->
.calledWith({url: "#{@Settings.apis.project_history.url}/project/#{@project_id}/flush", qs:{background:true}})
.should.equal true
describe "flushProjectChanges", ->
describe "in the normal case", ->
beforeEach ->
@request.post = sinon.stub().callsArgWith(1, null, statusCode: 204)
@HistoryManager.flushProjectChanges @project_id, {background:true}
it "should send a request to the project history api", ->
@request.post
.calledWith({url: "#{@Settings.apis.project_history.url}/project/#{@project_id}/flush", qs:{background:true}})
.should.equal true
describe "with the skip_history_flush option", ->
beforeEach ->
@request.post = sinon.stub()
@HistoryManager.flushProjectChanges @project_id, {skip_history_flush:true}
it "should not send a request to the project history api", ->
@request.post
.called
.should.equal false
describe "recordAndFlushHistoryOps", ->
beforeEach ->
@ops = [ 'mock-ops' ]

View file

@ -343,6 +343,17 @@ describe "HttpController", ->
it "should time the request", ->
@Metrics.Timer::done.called.should.equal true
describe "with the shutdown=true option from realtime", ->
beforeEach ->
@ProjectManager.flushAndDeleteProjectWithLocks = sinon.stub().callsArgWith(2)
@req.query = {background:true, shutdown:true}
@HttpController.deleteProject(@req, @res, @next)
it "should pass the skip_history_flush option when flushing the project", ->
@ProjectManager.flushAndDeleteProjectWithLocks
.calledWith(@project_id, {background:true, skip_history_flush:true})
.should.equal true
describe "when an errors occurs", ->
beforeEach ->
@ProjectManager.flushAndDeleteProjectWithLocks = sinon.stub().callsArgWith(2, new Error("oops"))