Răsfoiți Sursa

Merge pull request #26559 from overleaf/em-redis-buffer-delete

Delete project from redis buffer when expiring

GitOrigin-RevId: 66c48adc388a4a4e0b1b54b581dc945a38a41356
Eric Mc Sween 1 an în urmă
părinte
comite
a38eefd2ab

+ 15 - 0
services/history-v1/api/controllers/projects.js

@@ -18,6 +18,8 @@ const {
   HashCheckBlobStore,
   ProjectArchive,
   zipStore,
+  persistBuffer,
+  redisBuffer,
 } = require('../../storage')
 
 const render = require('./render')
@@ -226,6 +228,19 @@ async function createZip(req, res, next) {
 async function deleteProject(req, res, next) {
   const projectId = req.swagger.params.project_id.value
   const blobStore = new BlobStore(projectId)
+
+  const farFuture = new Date()
+  farFuture.setTime(farFuture.getTime() + 7 * 24 * 3600 * 1000)
+  const limits = {
+    maxChanges: 0,
+    minChangeTimestamp: farFuture,
+    maxChangeTimestamp: farFuture,
+    autoResync: false,
+  }
+
+  await persistBuffer(projectId, limits)
+  await redisBuffer.expireProject(projectId)
+
   await Promise.all([
     chunkStore.deleteProjectChunks(projectId),
     blobStore.deleteBlobs(),

+ 1 - 0
services/history-v1/storage/index.js

@@ -2,6 +2,7 @@ exports.BatchBlobStore = require('./lib/batch_blob_store')
 exports.blobHash = require('./lib/blob_hash')
 exports.HashCheckBlobStore = require('./lib/hash_check_blob_store')
 exports.chunkStore = require('./lib/chunk_store')
+exports.redisBuffer = require('./lib/chunk_store/redis')
 exports.historyStore = require('./lib/history_store').historyStore
 exports.knex = require('./lib/knex')
 exports.mongodb = require('./lib/mongodb')

+ 61 - 1
services/history-v1/test/acceptance/js/api/projects.test.js

@@ -10,7 +10,12 @@ const cleanup = require('../storage/support/cleanup')
 const fixtures = require('../storage/support/fixtures')
 const testFiles = require('../storage/support/test_files')
 
-const { zipStore, BlobStore, persistChanges } = require('../../../../storage')
+const {
+  zipStore,
+  BlobStore,
+  persistChanges,
+  redisBuffer,
+} = require('../../../../storage')
 
 const { expectHttpError } = require('./support/expect_response')
 const testServer = require('./support/test_server')
@@ -347,5 +352,60 @@ describe('project controller', function () {
       const response3 = await fetch(blobUrl, { headers: authHeaders })
       expect(response3.status).to.equal(HTTPStatus.NOT_FOUND)
     })
+
+    it('deletes the project from the redis buffer', async function () {
+      const projectId = await createEmptyProject()
+      const blobStore = new BlobStore(projectId)
+      const blob = await blobStore.putString('this is a test')
+      const snapshot = new Snapshot()
+      const change = new Change(
+        [new AddFileOperation('test.tex', File.createLazyFromBlobs(blob))],
+        new Date(),
+        []
+      )
+
+      await redisBuffer.queueChanges(projectId, snapshot, 0, [change])
+      const changesBefore = await redisBuffer.getNonPersistedChanges(
+        projectId,
+        0
+      )
+      expect(changesBefore.length).to.equal(1)
+
+      const deleteResponse =
+        await testServer.basicAuthClient.apis.Project.deleteProject({
+          project_id: projectId,
+        })
+      expect(deleteResponse.status).to.equal(HTTPStatus.NO_CONTENT)
+
+      const changesAfter = await redisBuffer.getNonPersistedChanges(
+        projectId,
+        0
+      )
+      expect(changesAfter.length).to.equal(0)
+
+      const finalState = await redisBuffer.getState(projectId)
+      expect(finalState).to.deep.equal({
+        changes: [],
+        expireTime: null,
+        headSnapshot: null,
+        headVersion: null,
+        persistTime: null,
+        persistedVersion: null,
+      })
+    })
+
+    it('deletes an empty project from the redis buffer', async function () {
+      const projectId = await createEmptyProject()
+      const deleteResponse =
+        await testServer.basicAuthClient.apis.Project.deleteProject({
+          project_id: projectId,
+        })
+      expect(deleteResponse.status).to.equal(HTTPStatus.NO_CONTENT)
+      const changesAfter = await redisBuffer.getNonPersistedChanges(
+        projectId,
+        0
+      )
+      expect(changesAfter.length).to.equal(0)
+    })
   })
 })