mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-08-08 21:38:37 +08:00
Ssynchronize push monitor heartbeats to api calls
Includes a 1s buffer time to allow the push url to be called before the monitor is checked
This commit is contained in:
@@ -173,7 +173,7 @@ class Monitor extends BeanModel {
|
||||
|
||||
let bean = R.dispense("heartbeat");
|
||||
bean.monitor_id = this.id;
|
||||
bean.time = R.isoDateTime(dayjs.utc());
|
||||
bean.time = R.isoDateTimeMillis(dayjs.utc());
|
||||
bean.status = DOWN;
|
||||
|
||||
if (this.isUpsideDown()) {
|
||||
@@ -348,25 +348,30 @@ class Monitor extends BeanModel {
|
||||
bean.msg = dnsMessage;
|
||||
bean.status = UP;
|
||||
} else if (this.type === "push") { // Type: Push
|
||||
const time = R.isoDateTime(dayjs.utc().subtract(this.interval, "second"));
|
||||
|
||||
let heartbeatCount = await R.count("heartbeat", " monitor_id = ? AND time > ? ", [
|
||||
this.id,
|
||||
time
|
||||
]);
|
||||
|
||||
log.debug("monitor", "heartbeatCount" + heartbeatCount + " " + time);
|
||||
|
||||
if (heartbeatCount <= 0) {
|
||||
// Fix #922, since previous heartbeat could be inserted by api, it should get from database
|
||||
previousBeat = await Monitor.getPreviousHeartbeat(this.id);
|
||||
|
||||
throw new Error("No heartbeat in the time window");
|
||||
} else {
|
||||
// No need to insert successful heartbeat for push type, so end here
|
||||
retries = 0;
|
||||
this.heartbeatInterval = setTimeout(beat, beatInterval * 1000);
|
||||
return;
|
||||
log.debug(`[${this.name}] Checking monitor at ${dayjs().format("YYYY-MM-DD HH:mm:ss.SSS")}`);
|
||||
const bufferTime = 1000; // 1s buffer to accommodate clock differences
|
||||
// Fix #922, since previous heartbeat could be inserted by api, it should get from database
|
||||
previousBeat = await Monitor.getPreviousHeartbeat(this.id);
|
||||
//If the previous beat was nonexistent, down or pending we use the regular
|
||||
// beatInterval/retryInterval in the setTimeout further below
|
||||
if (previousBeat) {
|
||||
const msSinceLastBeat = dayjs.utc().valueOf() - dayjs.utc(previousBeat.time).valueOf();
|
||||
log.debug(`[${this.name}] msSinceLastBeat = ${msSinceLastBeat}`);
|
||||
if (previousBeat.status !== UP || msSinceLastBeat > beatInterval * 1000 + bufferTime) {
|
||||
throw new Error("No heartbeat in the time window");
|
||||
} else {
|
||||
let timeout = beatInterval * 1000 - msSinceLastBeat;
|
||||
if (timeout < 0) {
|
||||
timeout = bufferTime;
|
||||
} else {
|
||||
timeout += bufferTime;
|
||||
}
|
||||
// No need to insert successful heartbeat for push type, so end here
|
||||
retries = 0;
|
||||
log.debug(`[${this.name}] timeout = ${timeout}`);
|
||||
this.heartbeatInterval = setTimeout(beat, timeout);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (this.type === "steam") {
|
||||
@@ -694,7 +699,7 @@ class Monitor extends BeanModel {
|
||||
|
||||
} else {
|
||||
// Handle new monitor with only one beat, because the beat's duration = 0
|
||||
let status = parseInt(await R.getCell("SELECT `status` FROM heartbeat WHERE monitor_id = ?", [monitorID]));
|
||||
let status = parseInt(await R.getCell("SELECT `status` FROM heartbeat WHERE monitor_id = ?", [ monitorID ]));
|
||||
|
||||
if (status === UP) {
|
||||
uptime = 1;
|
||||
|
Reference in New Issue
Block a user