[web] resync_projects: use the secondaries for all reads (#33684)

* [docstore] add useSecondary flag to projectHasRanges

The rev-check for unarchiving always consults with the primary.

Two extra changes:
- Add a projection argument to peekDoc in order to skip lines download
   from projectHasRanges.
- Add one retry to peekDoc to reduce chances of surfacing a rev-check
   violation.

* [web] resync_projects: use the secondaries for all reads

* [web] add default value for useSecondary

* [docstore] add default value for useSecondary

* [k8s] docstore: set MONGO_HAS_SECONDARIES=true

GitOrigin-RevId: f15ec4fdc1cabe74c1eab87bec85f28d6f7a587d
This commit is contained in:
Jakob Ackermann
2026-05-14 08:06:26 +00:00
committed by Copybot
parent ff53705bfa
commit 75a12dda17
7 changed files with 78 additions and 27 deletions
+40 -16
View File
@@ -77,15 +77,17 @@ const DocManager = {
},
// returns the doc without any version information
async _peekRawDoc(projectId, docId) {
const doc = await MongoManager.findDoc(projectId, docId, {
lines: true,
rev: true,
deleted: true,
version: true,
ranges: true,
inS3: true,
})
async _peekRawDoc(projectId, docId, projection, useSecondary) {
const doc = await MongoManager.findDoc(
projectId,
docId,
{
...projection,
rev: true,
inS3: true,
},
useSecondary
)
if (doc == null) {
throw new Errors.NotFoundError(
@@ -97,6 +99,8 @@ const DocManager = {
// skip the unarchiving to mongo when getting a doc
const archivedDoc = await DocArchive.getDoc(projectId, docId)
Object.assign(doc, archivedDoc)
// Always use the primary for the rev-check.
await MongoManager.checkRevUnchanged(doc)
}
return doc
@@ -104,10 +108,21 @@ const DocManager = {
// get the doc from mongo if possible, or from the persistent store otherwise,
// without unarchiving it (avoids unnecessary writes to mongo)
async peekDoc(projectId, docId) {
const doc = await DocManager._peekRawDoc(projectId, docId)
await MongoManager.checkRevUnchanged(doc)
return doc
async peekDoc(projectId, docId, projection, useSecondary = false) {
try {
return await DocManager._peekRawDoc(
projectId,
docId,
projection,
useSecondary
)
} catch (err) {
if (err instanceof Errors.DocModifiedError) {
// Try again once on rev mismatch. Always use the primary for retries.
return await DocManager._peekRawDoc(projectId, docId, projection, false)
}
throw err
}
},
async getDocLines(projectId, docId) {
@@ -181,11 +196,20 @@ const DocManager = {
return Array.from(userIds)
},
async projectHasRanges(projectId) {
const docs = await MongoManager.getProjectsDocs(projectId, {}, { _id: 1 })
async projectHasRanges(projectId, useSecondary) {
const docs = await MongoManager.getProjectsDocs(
projectId,
{ useSecondary },
{ _id: 1 }
)
const docIds = docs.map(doc => doc._id)
for (const docId of docIds) {
const doc = await DocManager.peekDoc(projectId, docId)
const doc = await DocManager.peekDoc(
projectId,
docId,
{ ranges: true },
useSecondary
)
if (
(doc.ranges?.comments != null && doc.ranges.comments.length > 0) ||
(doc.ranges?.changes != null && doc.ranges.changes.length > 0)