diff --git a/server/model/monitor.js b/server/model/monitor.js index c2d5a9a4..1a0ceb2a 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -6,7 +6,7 @@ const { log, UP, DOWN, PENDING, MAINTENANCE, flipStatus, TimeLogger, MAX_INTERVA SQL_DATETIME_FORMAT, isDev, sleep, getRandomInt } = require("../../src/util"); const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mysqlQuery, mqttAsync, setSetting, httpNtlm, radius, grpcQuery, - redisPingAsync, mongodbPing, kafkaProducerAsync, getOidcTokenClientCredentials, rootCertificatesFingerprints + redisPingAsync, mongodbPing, kafkaProducerAsync, getOidcTokenClientCredentials, rootCertificatesFingerprints, axiosAbortSignal } = require("../util-server"); const { R } = require("redbean-node"); const { BeanModel } = require("redbean-node/dist/bean-model"); @@ -475,6 +475,7 @@ class Monitor extends BeanModel { validateStatus: (status) => { return checkStatusCode(status, this.getAcceptedStatuscodes()); }, + signal: axiosAbortSignal(this.timeout * 1000), }; if (bodyValue) { diff --git a/server/util-server.js b/server/util-server.js index afb14749..adea303c 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -1124,3 +1124,26 @@ if (process.env.TEST_BACKEND) { return module.exports.__test[functionName]; }; } + +/** + * Generates an abort signal with the specified timeout. + * @param {number} timeoutMs - The timeout in milliseconds. + * @returns {AbortSignal | null} - The generated abort signal, or null if not supported. + */ +module.exports.axiosAbortSignal = (timeoutMs) => { + try { + return AbortSignal.timeout(timeoutMs); + } catch (_) { + // v16-: AbortSignal.timeout is not supported + try { + const abortController = new AbortController(); + + setTimeout(() => abortController.abort(), timeoutMs || 0); + + return abortController.signal; + } catch (_) { + // v15-: AbortController is not supported + return null; + } + } +};