Skip to content

Commit a1e660c

Browse files
committed
fix: node orphan process detection and exit logix to fix mac node termination on sleep
1 parent b7f71e7 commit a1e660c

File tree

4 files changed

+42
-27
lines changed

4 files changed

+42
-27
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-node/index.js

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ const rl = readline.createInterface({
103103
let serverPortResolve;
104104
const serverPortPromise = new Promise((resolve) => { serverPortResolve = resolve; });
105105

106-
let orphanExitTimer = setTimeout(()=>{
107-
process.exit(1);
108-
}, 60000);
109-
110106
function _sendResponse(responseMessage, commandID) {
111107
savedConsoleLog(COMMAND_RESPONSE_PREFIX + JSON.stringify({
112108
message: responseMessage,
@@ -153,15 +149,16 @@ process.on('uncaughtException', (error) => {
153149
_sendError(error, "uncaughtException");
154150
});
155151

156-
function resetOrphanExitTimer() {
157-
const timeout = debugMode ? 60000 * 15 : 60000;
158-
// in debug mode, we wait for more minutes to not exit node if phcode doesn't send heartbeats on break point debug
159-
clearTimeout(orphanExitTimer);
160-
orphanExitTimer = setTimeout(()=>{
161-
console.error(`Node did not receive heartbeat for ${timeout/1000}S, existing as orphan node process detected.`);
162-
process.exit(1);
163-
}, timeout);
164-
}
152+
// In the child process
153+
process.on('disconnect', () => {
154+
console.log('Parent process exited, exiting.');
155+
process.exit(1);
156+
});
157+
158+
rl.on('close', () => {
159+
console.log('Parent input stream is closed');
160+
process.exit(1);
161+
});
165162

166163
function processCommand(line) {
167164
try{
@@ -175,9 +172,6 @@ function processCommand(line) {
175172
process.exit(0);
176173
});
177174
return;
178-
case "heartBeat":
179-
resetOrphanExitTimer();
180-
return;
181175
case "ping": _sendResponse("pong", jsonCmd.commandID); return;
182176
case "setDebugMode":
183177
debugMode = jsonCmd.commandData;
@@ -187,7 +181,6 @@ function processCommand(line) {
187181
} else {
188182
console.log = function () {}; // swallow logs
189183
}
190-
resetOrphanExitTimer();
191184
_sendResponse("done", jsonCmd.commandID); return;
192185
case "getEndpoints":
193186
serverPortPromise.then(port =>{

src-node/node-connector.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,24 @@ const LARGE_DATA_THRESHOLD = 2*1024*1024; // 2MB
105105
let controlSocketMain = null,
106106
largeDataSocketMain = null;
107107

108+
const SOCKET_HEALTH_CHECK_INTERVAL_MS = 10 * 1000; // Interval in milliseconds
109+
let healthCheckFailuresCount = 0; // Count of consecutive health check failures
110+
const RETRY_HEALTH_CHECK_MAX_COUNT = 2;
111+
setInterval(() => {
112+
if (healthCheckFailuresCount === RETRY_HEALTH_CHECK_MAX_COUNT) {
113+
console.error(`No socket connection for ${healthCheckFailuresCount * SOCKET_HEALTH_CHECK_INTERVAL_MS / 1000} seconds. Exiting due to orphan node process detection.`);
114+
process.exit(1);
115+
}
116+
117+
if (controlSocketMain || largeDataSocketMain) {
118+
// Reset failure count if any socket is connected
119+
healthCheckFailuresCount = 0;
120+
return;
121+
}
122+
console.warn(`No active sockets detected, node will be terminated in ${(RETRY_HEALTH_CHECK_MAX_COUNT-healthCheckFailuresCount)*SOCKET_HEALTH_CHECK_INTERVAL_MS/1000} seconds`);
123+
healthCheckFailuresCount++;
124+
}, SOCKET_HEALTH_CHECK_INTERVAL_MS);
125+
108126
const MAX_PENDING_SEND_BUFFER = 10000;
109127
let pendingSendBuffer = [];
110128

src/node-loader.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ function nodeLoader() {
178178
return commandID;
179179
}
180180

181+
function _sendInitCommand(socket, commandCode) {
182+
currentCommandID++;
183+
const commandID = currentCommandID;
184+
socket.send(mergeMetadataAndArrayBuffer({
185+
commandCode: commandCode,
186+
commandID: commandID,
187+
data: null
188+
}, null));
189+
}
190+
181191
function _sendExec(nodeConnectorID, commandID, execHandlerFnName, dataObjectToSend = null, dataBuffer = null) {
182192
const command = {
183193
nodeConnectorID: nodeConnectorID,
@@ -521,9 +531,9 @@ function nodeLoader() {
521531
firstConnectCB();
522532
}
523533
if(ws.isLargeDataWS){
524-
_sendCommand(WS_COMMAND.LARGE_DATA_SOCKET_ANNOUNCE);
534+
_sendInitCommand(ws, WS_COMMAND.LARGE_DATA_SOCKET_ANNOUNCE);
525535
} else {
526-
_sendCommand(WS_COMMAND.CONTROL_SOCKET_ANNOUNCE);
536+
_sendInitCommand(ws, WS_COMMAND.CONTROL_SOCKET_ANNOUNCE);
527537
}
528538
_drainPendingSendBuffer();
529539
});
@@ -582,7 +592,6 @@ function nodeLoader() {
582592
TERMINATE: "terminate",
583593
PING: "ping",
584594
SET_DEBUG_MODE: "setDebugMode",
585-
HEART_BEAT: "heartBeat",
586595
GET_ENDPOINTS: "getEndpoints"
587596
};
588597
const COMMAND_RESPONSE_PREFIX = 'phnodeResp_1!5$:'; // a string thats not likely to just start with in
@@ -709,11 +718,6 @@ function nodeLoader() {
709718
window.PhNodeEngine._nodeLoadTime = Date.now() - nodeLoadstartTime;
710719
});
711720
execNode(NODE_COMMANDS.SET_DEBUG_MODE, window.debugMode);
712-
setInterval(()=>{
713-
if(!window.isNodeTerminated) {
714-
execNode(NODE_COMMANDS.HEART_BEAT);
715-
}
716-
}, 10000);
717721
});
718722
});
719723
}

0 commit comments

Comments
 (0)