فهرست منبع

Merge pull request #21706 from overleaf/bg-clear-projects-from-docupdater

clear inactive projects from docupdater when archiving

GitOrigin-RevId: 8fb11e6ebd29dfaafb62c10e07e774b90301b5ae
Brian Gough 1 سال پیش
والد
کامیت
527f56599f

+ 23 - 0
services/web/app/src/Features/InactiveData/InactiveProjectManager.js

@@ -1,12 +1,15 @@
 const OError = require('@overleaf/o-error')
 const logger = require('@overleaf/logger')
 const DocstoreManager = require('../Docstore/DocstoreManager')
+const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
 const ProjectGetter = require('../Project/ProjectGetter')
 const ProjectUpdateHandler = require('../Project/ProjectUpdateHandler')
 const { Project } = require('../../models/Project')
 const { ObjectId } = require('mongodb-legacy')
+const Modules = require('../../infrastructure/Modules')
 const { READ_PREFERENCE_SECONDARY } = require('../../infrastructure/mongodb')
 const { callbackifyAll } = require('@overleaf/promise-utils')
+const Metrics = require('@overleaf/metrics')
 
 const MILISECONDS_IN_DAY = 86400000
 const InactiveProjectManager = {
@@ -93,6 +96,26 @@ const InactiveProjectManager = {
   async deactivateProject(projectId) {
     logger.debug({ projectId }, 'deactivating inactive project')
 
+    // ensure project is removed from document updater (also flushes updates to history)
+    try {
+      await DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete(
+        projectId
+      )
+    } catch (err) {
+      logger.warn(
+        { err, projectId },
+        'error flushing project to mongo when archiving'
+      )
+      Metrics.inc('inactive-project', 1, {
+        method: 'archive',
+        status: 'flush-error',
+      })
+      throw err
+    }
+
+    await Modules.promises.hooks.fire('deactivateProject', projectId)
+
+    // now archive the project and mark it as inactive
     try {
       await DocstoreManager.promises.archiveProject(projectId)
       await ProjectUpdateHandler.promises.markAsInactive(projectId)

+ 25 - 1
services/web/test/unit/src/InactiveData/InactiveProjectManagerTests.js

@@ -11,12 +11,18 @@ const { expect } = require('chai')
 describe('InactiveProjectManager', function () {
   beforeEach(function () {
     this.settings = {}
+    this.metrics = { inc: sinon.stub() }
     this.DocstoreManager = {
       promises: {
         unarchiveProject: sinon.stub(),
         archiveProject: sinon.stub(),
       },
     }
+    this.DocumentUpdaterHandler = {
+      promises: {
+        flushProjectToMongoAndDelete: sinon.stub(),
+      },
+    }
     this.ProjectUpdateHandler = {
       promises: {
         markAsActive: sinon.stub(),
@@ -24,14 +30,19 @@ describe('InactiveProjectManager', function () {
       },
     }
     this.ProjectGetter = { promises: { getProject: sinon.stub() } }
+    this.Modules = { promises: { hooks: { fire: sinon.stub() } } }
     this.InactiveProjectManager = SandboxedModule.require(modulePath, {
       requires: {
         'mongodb-legacy': { ObjectId },
         '@overleaf/settings': this.settings,
+        '@overleaf/metrics': this.metrics,
         '../Docstore/DocstoreManager': this.DocstoreManager,
+        '../DocumentUpdater/DocumentUpdaterHandler':
+          this.DocumentUpdaterHandler,
         '../Project/ProjectUpdateHandler': this.ProjectUpdateHandler,
         '../Project/ProjectGetter': this.ProjectGetter,
         '../../models/Project': {},
+        '../../infrastructure/Modules': this.Modules,
         '../../infrastructure/mongodb': {
           ObjectId,
           READ_PREFERENCE_SECONDARY: ReadPreference.secondaryPreferred.mode,
@@ -94,13 +105,21 @@ describe('InactiveProjectManager', function () {
   })
 
   describe('deactivateProject', function () {
-    it('should call unarchiveProject and markAsInactive', async function () {
+    it('should call archiveProject and markAsInactive after flushing', async function () {
       this.DocstoreManager.promises.archiveProject.resolves()
+      this.DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete.resolves()
       this.ProjectUpdateHandler.promises.markAsInactive.resolves()
+      this.Modules.promises.hooks.fire.resolves()
 
       await this.InactiveProjectManager.promises.deactivateProject(
         this.project_id
       )
+      this.DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete
+        .calledWith(this.project_id)
+        .should.equal(true)
+      this.Modules.promises.hooks.fire
+        .calledWith('deactivateProject', this.project_id)
+        .should.equal(true)
       this.DocstoreManager.promises.archiveProject
         .calledWith(this.project_id)
         .should.equal(true)
@@ -111,11 +130,16 @@ describe('InactiveProjectManager', function () {
 
     it('should not call markAsInactive if there was a problem archiving in docstore', async function () {
       this.DocstoreManager.promises.archiveProject.rejects()
+      this.DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete.resolves()
       this.ProjectUpdateHandler.promises.markAsInactive.resolves()
+      this.Modules.promises.hooks.fire.resolves()
 
       await expect(
         this.InactiveProjectManager.promises.deactivateProject(this.project_id)
       ).to.be.rejected
+      this.DocumentUpdaterHandler.promises.flushProjectToMongoAndDelete
+        .calledWith(this.project_id)
+        .should.equal(true)
       this.DocstoreManager.promises.archiveProject
         .calledWith(this.project_id)
         .should.equal(true)