feat(cron): add 5-minute property index cronjob with change detection
deploy-chabokan / deploy (push) Canceled after 0s
deploy-chabokan / deploy (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
const { startPropertyIndexCron } = require('./propertyIndexCron')
|
||||||
|
|
||||||
|
const initCronJobs = () => {
|
||||||
|
startPropertyIndexCron()
|
||||||
|
console.log('Cron jobs initialized successfully')
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initCronJobs,
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
}
|
||||||
Generated
+10
@@ -23,6 +23,7 @@
|
|||||||
"mongoose": "^8.9.0",
|
"mongoose": "^8.9.0",
|
||||||
"mongoose-sequence": "^6.0.1",
|
"mongoose-sequence": "^6.0.1",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
|
"node-cron": "^4.6.0",
|
||||||
"typesense": "^1.8.2",
|
"typesense": "^1.8.2",
|
||||||
"validator": "^13.12.0"
|
"validator": "^13.12.0"
|
||||||
},
|
},
|
||||||
@@ -1572,6 +1573,15 @@
|
|||||||
"node": ">= 0.6"
|
"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": {
|
"node_modules/nodemon": {
|
||||||
"version": "3.1.9",
|
"version": "3.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"mongoose": "^8.9.0",
|
"mongoose": "^8.9.0",
|
||||||
"mongoose-sequence": "^6.0.1",
|
"mongoose-sequence": "^6.0.1",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
|
"node-cron": "^4.6.0",
|
||||||
"typesense": "^1.8.2",
|
"typesense": "^1.8.2",
|
||||||
"validator": "^13.12.0"
|
"validator": "^13.12.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ module.exports = (app) => {
|
|||||||
console.error('Failed to ensure default MinIO buckets:', err)
|
console.error('Failed to ensure default MinIO buckets:', err)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Initialize cron jobs
|
||||||
|
const { initCronJobs } = require('../jobs/index')
|
||||||
|
initCronJobs()
|
||||||
|
|
||||||
app.listen(port, function () {
|
app.listen(port, function () {
|
||||||
console.log('Server Started On Port ' + port)
|
console.log('Server Started On Port ' + port)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user