Просмотр исходного кода

Merge pull request #28431 from overleaf/em-docupdater-get-ranges

Look in docupdater when obtaining comments for DSMP

GitOrigin-RevId: acaead280f725da8e0c438d5b429fa983c3cad86
Eric Mc Sween 1 год назад
Родитель
Сommit
543f3fafcc

+ 2 - 0
services/document-updater/app.js

@@ -140,6 +140,8 @@ app.get(
   HttpController.getComment
 )
 app.get('/project/:project_id/doc/:doc_id/peek', HttpController.peekDoc)
+app.get('/project/:project_id/ranges', HttpController.getProjectRanges)
+
 // temporarily keep the GET method for backwards compatibility
 app.get('/project/:project_id/doc', HttpController.getProjectDocsAndFlushIfOld)
 // will migrate to the POST method of get_and_flush_if_old instead

+ 7 - 0
services/document-updater/app/js/HttpController.js

@@ -181,6 +181,12 @@ async function getProjectLastUpdatedAt(req, res) {
   res.json({ lastUpdatedAt: timestamps.pop() })
 }
 
+async function getProjectRanges(req, res) {
+  const projectId = req.params.project_id
+  const docs = await ProjectManager.promises.getProjectRanges(projectId)
+  res.json({ docs })
+}
+
 async function clearProjectState(req, res) {
   const projectId = req.params.project_id
   const timer = new Metrics.Timer('http.clearProjectState')
@@ -537,6 +543,7 @@ module.exports = {
   peekDoc: expressify(peekDoc),
   getProjectDocsAndFlushIfOld: expressify(getProjectDocsAndFlushIfOld),
   getProjectLastUpdatedAt: expressify(getProjectLastUpdatedAt),
+  getProjectRanges: expressify(getProjectRanges),
   clearProjectState: expressify(clearProjectState),
   appendToDoc: expressify(appendToDoc),
   setDoc: expressify(setDoc),

+ 11 - 0
services/document-updater/app/js/ProjectManager.js

@@ -118,6 +118,16 @@ async function getProjectDocsAndFlushIfOld(
   return docs
 }
 
+async function getProjectRanges(projectId) {
+  const docIds = await RedisManager.promises.getDocIdsInProject(projectId)
+  const docs = []
+  for (const docId of docIds) {
+    const ranges = await RedisManager.promises.getDocRanges(docId)
+    docs.push({ id: docId, ranges })
+  }
+  return docs
+}
+
 async function clearProjectState(projectId) {
   await RedisManager.promises.clearProjectState(projectId)
 }
@@ -234,6 +244,7 @@ const ProjectManager = {
   queueFlushAndDeleteProject,
   getProjectDocsTimestamps,
   getProjectDocsAndFlushIfOld,
+  getProjectRanges,
   clearProjectState,
   updateProjectWithLocks,
 }

+ 6 - 0
services/document-updater/app/js/RedisManager.js

@@ -296,6 +296,12 @@ const RedisManager = {
     }
   },
 
+  async getDocRanges(docId) {
+    const json = await rclient.get(keys.ranges({ doc_id: docId }))
+    const ranges = RedisManager._deserializeRanges(json)
+    return ranges
+  },
+
   async getDocVersion(docId) {
     const result = await rclient.mget(keys.docVersion({ doc_id: docId }))
     let [version] = result || []

+ 8 - 0
services/web/app/src/Features/DocumentUpdater/DocumentUpdaterHandler.js

@@ -24,6 +24,13 @@ async function getProjectLastUpdatedAt(projectId) {
   return body.lastUpdatedAt != null ? new Date(body.lastUpdatedAt) : null
 }
 
+async function getProjectRanges(projectId) {
+  const { docs } = await fetchJson(`${BASE_URL}/project/${projectId}/ranges`, {
+    signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
+  })
+  return docs
+}
+
 /**
  * @param {string} projectId
  */
@@ -518,6 +525,7 @@ const DocumentUpdaterHandler = {
   getComment,
   getDocument,
   getProjectLastUpdatedAt,
+  getProjectRanges,
   setDocument,
   appendToDocument,
   getProjectDocsIfMatch,

+ 21 - 0
services/web/test/acceptance/src/mocks/MockDocUpdaterApi.mjs

@@ -3,6 +3,7 @@ import AbstractMockApi from './AbstractMockApi.mjs'
 class MockDocUpdaterApi extends AbstractMockApi {
   reset() {
     this.updates = {}
+    this.docsByProject = new Map()
   }
 
   getProjectStructureUpdates(projectId) {
@@ -22,6 +23,15 @@ class MockDocUpdaterApi extends AbstractMockApi {
     this.updates[projectId].version = version
   }
 
+  setDoc(projectId, docId, lines, ranges) {
+    let docsById = this.docsByProject.get(projectId)
+    if (docsById == null) {
+      docsById = new Map()
+      this.docsByProject.set(projectId, docsById)
+    }
+    docsById.set(docId, { id: docId, lines, ranges })
+  }
+
   applyRoutes() {
     this.app.post('/project/:projectId/flush', (req, res) => {
       res.sendStatus(204)
@@ -68,6 +78,17 @@ class MockDocUpdaterApi extends AbstractMockApi {
     this.app.post('/project/:projectId/history/resync', (req, res) => {
       res.sendStatus(204)
     })
+
+    this.app.get('/project/:projectId/ranges', (req, res) => {
+      const docsById = this.docsByProject.get(req.params.projectId)
+      const docs = docsById == null ? [] : Array.from(docsById.values())
+      res.json({
+        docs: docs.map(doc => ({
+          id: doc.id,
+          ranges: doc.ranges,
+        })),
+      })
+    })
   }
 }