diff --git a/server/model/monitor.js b/server/model/monitor.js index 5dcb7171c..ef71eacc8 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -6,7 +6,7 @@ const { log, UP, DOWN, PENDING, MAINTENANCE, flipStatus, MAX_INTERVAL_SECOND, MI SQL_DATETIME_FORMAT } = require("../../src/util"); const { tcping, ping, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mysqlQuery, mqttAsync, setSetting, httpNtlm, radius, grpcQuery, - redisPingAsync, mongodbPing, kafkaProducerAsync, getOidcTokenClientCredentials, + redisPingAsync, mongodbPing, kafkaProducerAsync, getOidcTokenClientCredentials, axiosAbortSignal } = require("../util-server"); const { R } = require("redbean-node"); const { BeanModel } = require("redbean-node/dist/bean-model"); @@ -456,6 +456,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 181073843..ca8b5ce62 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -1095,3 +1095,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; + } + } +};