fix(cron): decouple cron from notification window
Some checks failed
/ build (map[dockerfile:./services/api/Dockerfile name:api]) (push) Successful in 1m10s
/ build (map[dockerfile:./services/app/Dockerfile name:app]) (push) Successful in 1m54s
/ build (map[dockerfile:./services/files/Dockerfile name:files]) (push) Successful in 1m36s
/ build (map[dockerfile:./services/hasura/Dockerfile name:hasura]) (push) Successful in 1m53s
/ build (map[dockerfile:./services/tasks/Dockerfile name:tasks]) (push) Successful in 1m56s
/ build (map[dockerfile:./services/watchers/Dockerfile name:watchers]) (push) Successful in 2m0s
/ build (map[dockerfile:./services/web/Dockerfile name:web]) (push) Has started running
/ deploy (push) Has been cancelled

This commit is contained in:
Jo 2025-07-23 15:20:13 +02:00
parent ace5657057
commit 6c1bb2fa3d
Signed by: devthejo
GPG key ID: 00CCA7A92B1D5351

View file

@ -9,7 +9,7 @@ const {
} = require("~/constants/time") } = require("~/constants/time")
const tasks = require("~/tasks") const tasks = require("~/tasks")
const CLEANUP_CRON = "0 9-19 * * *" // Run every hour from 9h to 19h const CLEANUP_CRON = "0 */4 * * *" // Run every 4 hours
const MAX_PARALLEL_PROCESS = 10 const MAX_PARALLEL_PROCESS = 10
const COLDGEODATA_DEVICE_KEY_PREFIX = "device:geodata:" const COLDGEODATA_DEVICE_KEY_PREFIX = "device:geodata:"
const COLDGEODATA_OLD_KEY_PREFIX = "old:device:geodata:" const COLDGEODATA_OLD_KEY_PREFIX = "old:device:geodata:"
@ -30,6 +30,13 @@ module.exports = async function () {
return async function geodataCleanupCron() { return async function geodataCleanupCron() {
logger.info("watcher geodataCleanupCron: daemon started") logger.info("watcher geodataCleanupCron: daemon started")
// Helper function to check if current time is within notification window (9-19h)
function isWithinNotificationWindow() {
const now = new Date()
const hour = now.getHours()
return hour >= 9 && hour < 19
}
// Process geodata cleanup with single loop for both notifications and cleanup // Process geodata cleanup with single loop for both notifications and cleanup
async function processGeodataCleanup() { async function processGeodataCleanup() {
const now = Math.floor(Date.now() / 1000) // Current time in seconds const now = Math.floor(Date.now() / 1000) // Current time in seconds
@ -107,7 +114,7 @@ module.exports = async function () {
) )
} }
} }
// Handle notification (36h+ but less than 48h) // Handle notification (36h+ but less than 48h) - only during 9-19h window
else if (age > notificationAge) { else if (age > notificationAge) {
const notifiedKey = `${COLDGEODATA_NOTIFIED_KEY_PREFIX}${deviceId}` const notifiedKey = `${COLDGEODATA_NOTIFIED_KEY_PREFIX}${deviceId}`
@ -115,7 +122,7 @@ module.exports = async function () {
// Check if we've already notified for this device // Check if we've already notified for this device
const alreadyNotified = await redisCold.exists(notifiedKey) const alreadyNotified = await redisCold.exists(notifiedKey)
if (!alreadyNotified) { if (!alreadyNotified && isWithinNotificationWindow()) {
// Enqueue task to notify user about lost background geolocation // Enqueue task to notify user about lost background geolocation
try { try {
await addTask(tasks.BACKGROUND_GEOLOCATION_LOST_NOTIFY, { await addTask(tasks.BACKGROUND_GEOLOCATION_LOST_NOTIFY, {
@ -134,6 +141,14 @@ module.exports = async function () {
} }
// Mark as notified with 48h expiry (cleanup age) // Mark as notified with 48h expiry (cleanup age)
await redisCold.set(notifiedKey, "1", "EX", cleanupAge) await redisCold.set(notifiedKey, "1", "EX", cleanupAge)
} else if (
!alreadyNotified &&
!isWithinNotificationWindow()
) {
logger.debug(
{ deviceId, age: `${Math.floor(age / 3600)}h` },
"Skipping notification outside business hours (9-19h)"
)
} }
} catch (error) { } catch (error) {
logger.error( logger.error(