Skip to content

Commit 1023d13

Browse files
committed
restore old heartbeat service but deprecate it
1 parent a434e98 commit 1023d13

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

packages/core/src/v3/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export {
6868

6969
export * from "./utils/imageRef.js";
7070
export * from "./utils/interval.js";
71+
export * from "./utils/heartbeat.js";
7172

7273
export * from "./config.js";
7374
export {
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
type HeartbeatServiceOptions = {
2+
heartbeat: () => Promise<void>;
3+
intervalMs?: number;
4+
leadingEdge?: boolean;
5+
onError?: (error: unknown) => Promise<void>;
6+
};
7+
8+
/**
9+
* @deprecated Use IntervalService instead
10+
*/
11+
export class HeartbeatService {
12+
private _heartbeat: () => Promise<void>;
13+
private _intervalMs: number;
14+
private _nextHeartbeat: NodeJS.Timeout | undefined;
15+
private _leadingEdge: boolean;
16+
private _isHeartbeating: boolean;
17+
private _onError?: (error: unknown) => Promise<void>;
18+
19+
constructor(opts: HeartbeatServiceOptions) {
20+
this._heartbeat = opts.heartbeat;
21+
this._intervalMs = opts.intervalMs ?? 45_000;
22+
this._nextHeartbeat = undefined;
23+
this._leadingEdge = opts.leadingEdge ?? false;
24+
this._isHeartbeating = false;
25+
this._onError = opts.onError;
26+
}
27+
28+
start() {
29+
if (this._isHeartbeating) {
30+
return;
31+
}
32+
33+
this._isHeartbeating = true;
34+
35+
if (this._leadingEdge) {
36+
this.#doHeartbeat();
37+
} else {
38+
this.#scheduleNextHeartbeat();
39+
}
40+
}
41+
42+
stop() {
43+
if (!this._isHeartbeating) {
44+
return;
45+
}
46+
47+
this._isHeartbeating = false;
48+
this.#clearNextHeartbeat();
49+
}
50+
51+
resetCurrentInterval() {
52+
if (!this._isHeartbeating) {
53+
return;
54+
}
55+
56+
this.#clearNextHeartbeat();
57+
this.#scheduleNextHeartbeat();
58+
}
59+
60+
updateInterval(intervalMs: number) {
61+
this._intervalMs = intervalMs;
62+
this.resetCurrentInterval();
63+
}
64+
65+
#doHeartbeat = async () => {
66+
this.#clearNextHeartbeat();
67+
68+
if (!this._isHeartbeating) {
69+
return;
70+
}
71+
72+
try {
73+
await this._heartbeat();
74+
} catch (error) {
75+
if (this._onError) {
76+
try {
77+
await this._onError(error);
78+
} catch (error) {
79+
console.error("Error handling heartbeat error", error);
80+
}
81+
}
82+
}
83+
84+
this.#scheduleNextHeartbeat();
85+
};
86+
87+
#clearNextHeartbeat() {
88+
if (this._nextHeartbeat) {
89+
clearTimeout(this._nextHeartbeat);
90+
}
91+
}
92+
93+
#scheduleNextHeartbeat() {
94+
this._nextHeartbeat = setTimeout(this.#doHeartbeat, this._intervalMs);
95+
}
96+
}

0 commit comments

Comments
 (0)