Procházet zdrojové kódy

[web] start fetching load global blobs on module import (#25757)

GitOrigin-RevId: 7c1b6ed717142ad07d6ba5464aab2ecc6ebe9736
Jakob Ackermann před 1 rokem
rodič
revize
47b76a49d8

+ 1 - 1
services/web/app.mjs

@@ -75,7 +75,7 @@ try {
   await Promise.all([
     mongodb.connectionPromise,
     mongoose.connectionPromise,
-    HistoryManager.promises.loadGlobalBlobs(),
+    HistoryManager.loadGlobalBlobsPromise,
   ])
 } catch (err) {
   logger.fatal({ err }, 'Cannot connect to mongo. Exiting.')

+ 3 - 1
services/web/app/src/Features/History/HistoryManager.js

@@ -417,8 +417,11 @@ function _userView(user) {
   return { first_name: firstName, last_name: lastName, email, id: _id }
 }
 
+const loadGlobalBlobsPromise = loadGlobalBlobs()
+
 module.exports = {
   getBlobLocation,
+  loadGlobalBlobsPromise,
   initializeProject: callbackify(initializeProject),
   flushProject: callbackify(flushProject),
   resyncProject: callbackify(resyncProject),
@@ -432,7 +435,6 @@ module.exports = {
   getLatestHistory: callbackify(getLatestHistory),
   getChanges: callbackify(getChanges),
   promises: {
-    loadGlobalBlobs,
     initializeProject,
     flushProject,
     resyncProject,

+ 53 - 1
services/web/test/unit/src/History/HistoryManagerTests.js

@@ -2,10 +2,36 @@ const { expect } = require('chai')
 const sinon = require('sinon')
 const SandboxedModule = require('sandboxed-module')
 const { ObjectId } = require('mongodb-legacy')
+const {
+  connectionPromise,
+  cleanupTestDatabase,
+  db,
+} = require('../../../../app/src/infrastructure/mongodb')
 
 const MODULE_PATH = '../../../../app/src/Features/History/HistoryManager'
 
+const GLOBAL_BLOBS = {
+  e69de29bb2d1d6434b8b29ae775ad8c2e48c5391:
+    'e6/9d/e29bb2d1d6434b8b29ae775ad8c2e48c5391',
+  '02426c2b3a484003ca42ed52b374b7907b757d12':
+    '02/42/6c2b3a484003ca42ed52b374b7907b757d12',
+}
+
 describe('HistoryManager', function () {
+  before(async function () {
+    await connectionPromise
+  })
+  before(cleanupTestDatabase)
+  before(async function () {
+    await db.projectHistoryGlobalBlobs.insertMany(
+      Object.keys(GLOBAL_BLOBS).map(sha => ({
+        _id: sha,
+        byteLength: 0,
+        stringLength: 0,
+      }))
+    )
+  })
+
   beforeEach(function () {
     this.user_id = 'user-id-123'
     this.historyId = new ObjectId().toString()
@@ -29,6 +55,10 @@ describe('HistoryManager', function () {
           url: this.v1HistoryUrl,
           user: this.v1HistoryUser,
           pass: this.v1HistoryPassword,
+          buckets: {
+            globalBlobs: 'globalBlobs',
+            projectBlobs: 'projectBlobs',
+          },
         },
       },
     }
@@ -60,7 +90,7 @@ describe('HistoryManager', function () {
 
     this.HistoryManager = SandboxedModule.require(MODULE_PATH, {
       requires: {
-        '../../infrastructure/mongodb': { ObjectId },
+        '../../infrastructure/mongodb': { ObjectId, db },
         '@overleaf/fetch-utils': this.FetchUtils,
         '@overleaf/settings': this.settings,
         '../User/UserGetter': this.UserGetter,
@@ -70,6 +100,28 @@ describe('HistoryManager', function () {
     })
   })
 
+  describe('getBlobLocation', function () {
+    beforeEach(async function () {
+      await this.HistoryManager.loadGlobalBlobsPromise
+    })
+    it('should return a global blob location', function () {
+      for (const [sha, key] of Object.entries(GLOBAL_BLOBS)) {
+        expect(this.HistoryManager.getBlobLocation('42', sha)).to.deep.equal({
+          bucket: this.settings.apis.v1_history.buckets.globalBlobs,
+          key,
+        })
+      }
+    })
+    it('should return a project blob location', function () {
+      const sha = '6ddfa0578a67fe5ad6623a8665ec9aafce1eb5ca'
+      const key = '240/000/000/6d/dfa0578a67fe5ad6623a8665ec9aafce1eb5ca'
+      expect(this.HistoryManager.getBlobLocation('42', sha)).to.deep.equal({
+        bucket: this.settings.apis.v1_history.buckets.projectBlobs,
+        key,
+      })
+    })
+  })
+
   describe('initializeProject', function () {
     beforeEach(function () {
       this.settings.apis.project_history.initializeHistoryForNewProjects = true