Skip to content

Commit

Permalink
Naively synchronize push monitor heartbeats to api calls
Browse files Browse the repository at this point in the history
Includes a 1s buffer time
Does not handle retries
  • Loading branch information
kaysond committed Apr 4, 2022
1 parent aef7719 commit 85a5d9c
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 19 deletions.
43 changes: 24 additions & 19 deletions server/model/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,25 +307,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
]);

debug("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;
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()
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;
debug(`[${this.name}] timeout = ${timeout}`)
this.heartbeatInterval = setTimeout(beat, timeout);
return;
}
}

} else if (this.type === "steam") {
Expand Down
1 change: 1 addition & 0 deletions server/routers/api-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ router.get("/api/push/:pushToken", async (request, response) => {
duration = dayjs(bean.time).diff(dayjs(previousHeartbeat.time), "second");
}

debug(`/api/push/ called at ${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')}`)
debug("PreviousStatus: " + previousStatus);
debug("Current Status: " + status);

Expand Down

0 comments on commit 85a5d9c

Please sign in to comment.