Skip to content

Commit 3a9b032

Browse files
authored
Add heartbeat file (#1115)
Fixes #1050.
1 parent f73e922 commit 3a9b032

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

src/node/server.ts

+49
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,9 @@ export class MainServer extends Server {
474474
private readonly proxyTimeout = 5000;
475475

476476
private settings: Settings = {};
477+
private heartbeatTimer?: NodeJS.Timeout;
478+
private heartbeatInterval = 60000;
479+
private lastHeartbeat = 0;
477480

478481
public constructor(options: ServerOptions, args: ParsedArgs) {
479482
super(options);
@@ -491,6 +494,7 @@ export class MainServer extends Server {
491494
}
492495

493496
protected async handleWebSocket(socket: net.Socket, parsedUrl: url.UrlWithParsedQuery): Promise<void> {
497+
this.heartbeat();
494498
if (!parsedUrl.query.reconnectionToken) {
495499
throw new Error("Reconnection token is missing from query parameters");
496500
}
@@ -514,6 +518,7 @@ export class MainServer extends Server {
514518
parsedUrl: url.UrlWithParsedQuery,
515519
request: http.IncomingMessage,
516520
): Promise<Response> {
521+
this.heartbeat();
517522
switch (base) {
518523
case "/": return this.getRoot(request, parsedUrl);
519524
case "/resource":
@@ -876,4 +881,48 @@ export class MainServer extends Server {
876881
(this.services.get(ILogService) as ILogService).warn(error.message);
877882
}
878883
}
884+
885+
/**
886+
* Return the file path for the heartbeat file.
887+
*/
888+
private get heartbeatPath(): string {
889+
const environment = this.services.get(IEnvironmentService) as IEnvironmentService;
890+
return path.join(environment.userDataPath, "heartbeat");
891+
}
892+
893+
/**
894+
* Return all online connections regardless of type.
895+
*/
896+
private get onlineConnections(): Connection[] {
897+
const online = <Connection[]>[];
898+
this.connections.forEach((connections) => {
899+
connections.forEach((connection) => {
900+
if (typeof connection.offline === "undefined") {
901+
online.push(connection);
902+
}
903+
});
904+
});
905+
return online;
906+
}
907+
908+
/**
909+
* Write to the heartbeat file if we haven't already done so within the
910+
* timeout and start or reset a timer that keeps running as long as there are
911+
* active connections. Failures are logged as warnings.
912+
*/
913+
private heartbeat(): void {
914+
const now = Date.now();
915+
if (now - this.lastHeartbeat >= this.heartbeatInterval) {
916+
util.promisify(fs.writeFile)(this.heartbeatPath, "").catch((error) => {
917+
(this.services.get(ILogService) as ILogService).warn(error.message);
918+
});
919+
this.lastHeartbeat = now;
920+
clearTimeout(this.heartbeatTimer!); // We can clear undefined so ! is fine.
921+
this.heartbeatTimer = setTimeout(() => {
922+
if (this.onlineConnections.length > 0) {
923+
this.heartbeat();
924+
}
925+
}, this.heartbeatInterval);
926+
}
927+
}
879928
}

0 commit comments

Comments
 (0)