From 88eb599d4e2bc80e202444c28d064d9e36bfc02f Mon Sep 17 00:00:00 2001 From: Kristina <7614497+khjrtbrg@users.noreply.github.com> Date: Thu, 21 May 2026 13:21:36 +0200 Subject: [PATCH] [document-updater] increase scanStream COUNT for project notifications (#33833) * increase scanStream COUNT for project notifications * fix Bull queue.add delay option being ignored * parse timestamp to number before adding to notification queue * fix outdated comments in project_notifications script GitOrigin-RevId: 98bb638228550b2f6f2de90280a06c47e022cf96 --- .../scripts/project_notifications.mts | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/services/document-updater/scripts/project_notifications.mts b/services/document-updater/scripts/project_notifications.mts index 9cb99b6ec7..47f056070b 100644 --- a/services/document-updater/scripts/project_notifications.mts +++ b/services/document-updater/scripts/project_notifications.mts @@ -21,13 +21,13 @@ const argv = minimist(process.argv.slice(2), { if (argv.help) { console.log(` -project_notifications.ts - Queue project update notifications +project_notifications.mts - Queue project update notifications This script scans Redis for projects that have pending notification timestamps and queues them for notification. It's used to notify project collaborators when changes have been made to a project. Only projects with collaborators are processed. -Usage: project_notifications.ts [options] +Usage: node scripts/project_notifications.mts [options] Options: -n, --dry-run Show what would be done without making changes @@ -35,10 +35,10 @@ Options: Examples: # Dry run to see what would be notified - project_notifications.ts --dry-run + node scripts/project_notifications.mts --dry-run # Actually queue the notifications - project_notifications.ts + node scripts/project_notifications.mts `) process.exit(0) } @@ -97,7 +97,7 @@ async function main() { if (dryRun) { console.log('\n[DRY RUN] Projects that would be queued:') for (const { projectId, timestamp } of projects) { - const date = new Date(parseInt(timestamp)) + const date = new Date(parseInt(timestamp, 10)) console.log( ` ${projectId}: ${timestamp} (${date.toISOString()}) - would be queued` ) @@ -110,13 +110,12 @@ async function main() { console.log('Queue is ready.') for (const { projectId, timestamp } of projects) { + const numericTimestamp = parseInt(timestamp, 10) try { await projectNotificationQueue.add( - { projectId, timestamp }, + { projectId, timestamp: numericTimestamp }, { jobId: projectId, - }, - { delay: 1000, } ) @@ -124,7 +123,7 @@ async function main() { // Delete the timestamp key after scheduling (only if it still matches) await deleteProjectNotificationTimestamp(projectId, timestamp) - const date = new Date(parseInt(timestamp)) + const date = new Date(numericTimestamp) console.log( ` ${projectId}: ${timestamp} (${date.toISOString()}) - queued` ) @@ -155,7 +154,7 @@ type ProjectNotification = { /** * Check if a project has any collaborators (excluding owner) - * Uses Redis caching with 1 hour expiration to avoid repeated MongoDB queries + * Uses Redis caching with 1-2 hour randomized expiration to avoid repeated MongoDB queries */ async function projectHasCollaborators(projectId: string): Promise { // Check Redis cache first @@ -185,7 +184,7 @@ async function projectHasCollaborators(projectId: string): Promise { const randomTTL = 3600 + Math.floor(Math.random() * 3600) if (hasCollaborators === null) { - // Cache false result for non-existent projects + // Cache negative result (no collaborators or project not found) await redisClient.setex(cacheKey, randomTTL, '0') return false } @@ -212,6 +211,7 @@ async function getProjectsToNotify(): Promise { // Scan for all ProjectNotificationTimestamp keys const stream = node.scanStream({ match: docUpdaterKeys.projectNotificationTimestamp({ project_id: '*' }), + count: 1000, }) for await (const keys of stream) { @@ -246,6 +246,14 @@ async function getProjectsToNotify(): Promise { continue } + const numericTimestamp = parseInt(timestamp, 10) + if (Number.isNaN(numericTimestamp)) { + console.log( + `Skipping project ${projectId} - non-numeric timestamp: ${timestamp}` + ) + continue + } + projects.push({ projectId, timestamp }) } }