2025-07-25 15:15:14 -07:00
|
|
|
const SERVICE_NAME = "JobQueueHelper";
|
2025-06-27 12:38:06 +08:00
|
|
|
|
|
|
|
|
class SuperSimpleQueueHelper {
|
2025-07-25 15:15:14 -07:00
|
|
|
static SERVICE_NAME = SERVICE_NAME;
|
2025-08-18 10:55:12 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {{
|
2025-09-23 14:23:45 -07:00
|
|
|
* db: import("../database.js").Database,
|
|
|
|
|
* logger: import("../logger.js").Logger,
|
|
|
|
|
* networkService: import("../networkService.js").NetworkService,
|
|
|
|
|
* statusService: import("../statusService.js").StatusService,
|
|
|
|
|
* notificationService: import("../notificationService.js").NotificationService
|
2025-08-18 10:55:12 -07:00
|
|
|
* }}
|
|
|
|
|
*/
|
2025-06-27 12:38:06 +08:00
|
|
|
constructor({ db, logger, networkService, statusService, notificationService }) {
|
|
|
|
|
this.db = db;
|
|
|
|
|
this.logger = logger;
|
|
|
|
|
this.networkService = networkService;
|
|
|
|
|
this.statusService = statusService;
|
|
|
|
|
this.notificationService = notificationService;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-25 15:15:14 -07:00
|
|
|
get serviceName() {
|
|
|
|
|
return SuperSimpleQueueHelper.SERVICE_NAME;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-27 12:38:06 +08:00
|
|
|
getMonitorJob = () => {
|
|
|
|
|
return async (monitor) => {
|
|
|
|
|
try {
|
2026-01-13 20:20:00 +00:00
|
|
|
const monitorId = monitor.id;
|
2025-09-15 12:28:37 -04:00
|
|
|
const teamId = monitor.teamId;
|
2025-06-27 12:38:06 +08:00
|
|
|
if (!monitorId) {
|
|
|
|
|
throw new Error("No monitor id");
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-15 12:28:37 -04:00
|
|
|
const maintenanceWindowActive = await this.isInMaintenanceWindow(monitorId, teamId);
|
2025-06-27 12:38:06 +08:00
|
|
|
if (maintenanceWindowActive) {
|
|
|
|
|
this.logger.info({
|
|
|
|
|
message: `Monitor ${monitorId} is in maintenance window`,
|
|
|
|
|
service: SERVICE_NAME,
|
|
|
|
|
method: "getMonitorJob",
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-08-15 16:04:43 -07:00
|
|
|
const networkResponse = await this.networkService.requestStatus(monitor);
|
|
|
|
|
|
2025-06-27 12:38:06 +08:00
|
|
|
if (!networkResponse) {
|
|
|
|
|
throw new Error("No network response");
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-23 13:04:26 -07:00
|
|
|
const { monitor: updatedMonitor, statusChanged, prevStatus } = await this.statusService.updateStatus(networkResponse);
|
2025-06-27 12:38:06 +08:00
|
|
|
|
|
|
|
|
this.notificationService
|
|
|
|
|
.handleNotifications({
|
|
|
|
|
...networkResponse,
|
|
|
|
|
monitor: updatedMonitor,
|
|
|
|
|
prevStatus,
|
|
|
|
|
statusChanged,
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
this.logger.error({
|
|
|
|
|
message: error.message,
|
|
|
|
|
service: SERVICE_NAME,
|
|
|
|
|
method: "getMonitorJob",
|
2026-01-13 20:20:00 +00:00
|
|
|
details: `Error sending notifications for job ${monitor.id}: ${error.message}`,
|
2025-06-27 12:38:06 +08:00
|
|
|
stack: error.stack,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
this.logger.warn({
|
|
|
|
|
message: error.message,
|
|
|
|
|
service: error.service || SERVICE_NAME,
|
|
|
|
|
method: error.method || "getMonitorJob",
|
|
|
|
|
stack: error.stack,
|
|
|
|
|
});
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2025-09-15 12:28:37 -04:00
|
|
|
async isInMaintenanceWindow(monitorId, teamId) {
|
|
|
|
|
const maintenanceWindows = await this.db.maintenanceWindowModule.getMaintenanceWindowsByMonitorId({
|
|
|
|
|
monitorId: monitorId.toString(),
|
|
|
|
|
teamId: teamId.toString(),
|
|
|
|
|
});
|
2025-06-27 12:38:06 +08:00
|
|
|
// Check for active maintenance window:
|
|
|
|
|
const maintenanceWindowIsActive = maintenanceWindows.reduce((acc, window) => {
|
|
|
|
|
if (window.active) {
|
|
|
|
|
const start = new Date(window.start);
|
|
|
|
|
const end = new Date(window.end);
|
|
|
|
|
const now = new Date();
|
|
|
|
|
const repeatInterval = window.repeat || 0;
|
|
|
|
|
|
|
|
|
|
// If start is < now and end > now, we're in maintenance
|
|
|
|
|
if (start <= now && end >= now) return true;
|
|
|
|
|
|
|
|
|
|
// If maintenance window was set in the past with a repeat,
|
|
|
|
|
// we need to advance start and end to see if we are in range
|
|
|
|
|
|
|
|
|
|
while (start < now && repeatInterval !== 0) {
|
|
|
|
|
start.setTime(start.getTime() + repeatInterval);
|
|
|
|
|
end.setTime(end.getTime() + repeatInterval);
|
|
|
|
|
if (start <= now && end >= now) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return acc;
|
|
|
|
|
}, false);
|
|
|
|
|
return maintenanceWindowIsActive;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default SuperSimpleQueueHelper;
|