diff --git a/jobs/index.js b/jobs/index.js new file mode 100644 index 0000000..be396db --- /dev/null +++ b/jobs/index.js @@ -0,0 +1,10 @@ +const { startPropertyIndexCron } = require('./propertyIndexCron') + +const initCronJobs = () => { + startPropertyIndexCron() + console.log('Cron jobs initialized successfully') +} + +module.exports = { + initCronJobs, +} diff --git a/jobs/propertyIndexCron.js b/jobs/propertyIndexCron.js new file mode 100644 index 0000000..b7c0e9d --- /dev/null +++ b/jobs/propertyIndexCron.js @@ -0,0 +1,90 @@ +const cron = require('node-cron') +const Property = require('../components/property/propertyModel') +const propertyService = require('../components/property/propertyService') +const { client } = require('../setup/typesense') + +let lastIndexedAt = new Date(0) +let lastIndexedCount = null +let isIndexing = false + +const checkAndIndexProperties = async () => { + if (isIndexing) { + console.log('[Property Index Cron] Indexing already in progress. Skipping this run.') + return + } + + isIndexing = true + try { + const mongoCount = await Property.countDocuments({ isActive: true }) + + // Check Typesense collection document count + let typesenseCount = 0 + let collectionExists = false + try { + const collection = await client.collections('properties').retrieve() + typesenseCount = collection.num_documents || 0 + collectionExists = true + } catch (err) { + collectionExists = false + } + + // Count new or updated properties in MongoDB since last index + const query = { + isActive: true, + $or: [ + { updatedAt: { $gt: lastIndexedAt } }, + { createdAt: { $gt: lastIndexedAt } } + ] + } + const changedCount = await Property.countDocuments(query) + + const shouldIndex = + !collectionExists || + (typesenseCount === 0 && mongoCount > 0) || + mongoCount !== typesenseCount || + (lastIndexedCount !== null && mongoCount !== lastIndexedCount) || + changedCount > 0 + + if (shouldIndex) { + console.log( + `[Property Index Cron] Changes detected (MongoDB: ${mongoCount}, Typesense: ${typesenseCount}, New/Updated: ${changedCount}). Starting indexing...` + ) + const result = await propertyService.indexAllProperties() + lastIndexedAt = new Date() + lastIndexedCount = mongoCount + console.log(`[Property Index Cron] Successfully indexed ${result.totalCount} properties.`) + } else { + console.log( + `[Property Index Cron] No new or updated properties found since ${lastIndexedAt.toISOString()} (MongoDB: ${mongoCount}, Typesense: ${typesenseCount}). Skipping.` + ) + } + } catch (err) { + console.error('[Property Index Cron] Error during property indexing check:', err) + } finally { + isIndexing = false + } +} + +const startPropertyIndexCron = () => { + // Schedule every 5 minutes + const task = cron.schedule('*/5 * * * *', async () => { + console.log('[Property Index Cron] Running scheduled 5-minute property index check...') + await checkAndIndexProperties() + }) + + console.log('[Property Index Cron] Scheduled to run every 5 minutes (*/5 * * * *)') + + // Initial check after startup + setTimeout(() => { + checkAndIndexProperties().catch((err) => { + console.error('[Property Index Cron] Initial index check failed:', err) + }) + }, 10000) + + return task +} + +module.exports = { + startPropertyIndexCron, + checkAndIndexProperties, +} diff --git a/package-lock.json b/package-lock.json index 9e3cd7e..d799fb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "mongoose": "^8.9.0", "mongoose-sequence": "^6.0.1", "multer": "^1.4.5-lts.1", + "node-cron": "^4.6.0", "typesense": "^1.8.2", "validator": "^13.12.0" }, @@ -1572,6 +1573,15 @@ "node": ">= 0.6" } }, + "node_modules/node-cron": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-4.6.0.tgz", + "integrity": "sha512-Si/bzYiKRHOB8/a99T2+SDGN582ONDMSTlJr5oCkT6GtnqPjZ2s10eoQRYkW9ZHwjVxONL+W8Fb+qR0AHMQsdg==", + "license": "ISC", + "engines": { + "node": ">=20" + } + }, "node_modules/nodemon": { "version": "3.1.9", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz", diff --git a/package.json b/package.json index ba79a8e..59c4e4e 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "mongoose": "^8.9.0", "mongoose-sequence": "^6.0.1", "multer": "^1.4.5-lts.1", + "node-cron": "^4.6.0", "typesense": "^1.8.2", "validator": "^13.12.0" }, diff --git a/setup/databaseConnection.js b/setup/databaseConnection.js index 92f92b2..d935718 100644 --- a/setup/databaseConnection.js +++ b/setup/databaseConnection.js @@ -29,6 +29,10 @@ module.exports = (app) => { console.error('Failed to ensure default MinIO buckets:', err) }) + // Initialize cron jobs + const { initCronJobs } = require('../jobs/index') + initCronJobs() + app.listen(port, function () { console.log('Server Started On Port ' + port) })