feat: optional instant retry before marking a monitor down
Adds per-monitor `retries` and `retryDelayMs` options. When a check fails, the monitor is re-checked up to `retries` extra times (waiting `retryDelayMs` between attempts, default 5000ms) before being reported as down. This filters out transient blips / false positives, and affects both the status page state and downtime notifications. Backward compatible: default `retries: 0` keeps the current behavior (no retry). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>pull/212/head
parent
a5670e51cb
commit
eb449a335f
|
|
@ -45,6 +45,11 @@ export type MonitorTarget = {
|
||||||
responseForbiddenKeyword?: string
|
responseForbiddenKeyword?: string
|
||||||
checkProxy?: string
|
checkProxy?: string
|
||||||
checkProxyFallback?: boolean
|
checkProxyFallback?: boolean
|
||||||
|
// [OPTIONAL] Instant retry on failure: number of extra attempts before reporting
|
||||||
|
// the monitor as down (default 0 = no retry). Filters out transient blips.
|
||||||
|
retries?: number
|
||||||
|
// [OPTIONAL] Delay in ms between a failed attempt and the retry (default 5000).
|
||||||
|
retryDelayMs?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WorkerConfig<TEnv = Env> = {
|
export type WorkerConfig<TEnv = Env> = {
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,11 @@ const workerConfig: WorkerConfig = {
|
||||||
checkProxy: 'https://xxx.example.com OR worker://weur',
|
checkProxy: 'https://xxx.example.com OR worker://weur',
|
||||||
// [OPTIONAL] if true, the check will fallback to local if the specified proxy is down
|
// [OPTIONAL] if true, the check will fallback to local if the specified proxy is down
|
||||||
checkProxyFallback: true,
|
checkProxyFallback: true,
|
||||||
|
// [OPTIONAL] instant retry on failure: number of extra attempts before reporting
|
||||||
|
// the monitor as down, to filter out transient blips (default 0 = no retry)
|
||||||
|
retries: 1,
|
||||||
|
// [OPTIONAL] delay in ms between a failed attempt and the retry (default 5000)
|
||||||
|
retryDelayMs: 5000,
|
||||||
},
|
},
|
||||||
// Example TCP Monitor
|
// Example TCP Monitor
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,16 @@ export async function getStatus(
|
||||||
|
|
||||||
export async function doMonitor(monitor: MonitorTarget, defaultLocation: string, env: Env) {
|
export async function doMonitor(monitor: MonitorTarget, defaultLocation: string, env: Env) {
|
||||||
let checkLocation = defaultLocation
|
let checkLocation = defaultLocation
|
||||||
let status
|
let status: { ping: number; up: boolean; err: string } = { ping: 0, up: false, err: '' }
|
||||||
|
|
||||||
|
// Instant retry: if a check fails, re-check before reporting the monitor as down,
|
||||||
|
// to filter out transient blips (false positives). Controlled per-monitor via
|
||||||
|
// `retries` / `retryDelayMs` (default 0 retries = previous behavior, no retry).
|
||||||
|
const maxAttempts = 1 + (monitor.retries ?? 0)
|
||||||
|
const retryDelayMs = monitor.retryDelayMs ?? 5000
|
||||||
|
|
||||||
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
checkLocation = defaultLocation
|
||||||
|
|
||||||
if (monitor.checkProxy) {
|
if (monitor.checkProxy) {
|
||||||
// Initiate a check using proxy (Geo-specific monitoring)
|
// Initiate a check using proxy (Geo-specific monitoring)
|
||||||
|
|
@ -404,6 +413,13 @@ export async function doMonitor(monitor: MonitorTarget, defaultLocation: string,
|
||||||
status = await getStatus(monitor)
|
status = await getStatus(monitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status.up || attempt === maxAttempts) break
|
||||||
|
console.log(
|
||||||
|
`[${monitor.id}] Attempt ${attempt}/${maxAttempts} failed (${status.err}); retrying in ${retryDelayMs}ms...`
|
||||||
|
)
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, retryDelayMs))
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`[${monitor.id}] Check result from ${checkLocation}: up=${status.up}, ping=${status.ping}, err=${status.err}`)
|
console.log(`[${monitor.id}] Check result from ${checkLocation}: up=${status.up}, ping=${status.ping}, err=${status.err}`)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue