@mytec: iter2.3 multithreading p1 done
This commit is contained in:
@@ -8,7 +8,9 @@ const store = new Store();
|
||||
let mainWindow;
|
||||
let splashWindow;
|
||||
let backendProcess;
|
||||
let backendPid = null; // Store PID separately — survives even if backendProcess ref is lost
|
||||
let backendLogStream;
|
||||
let isQuitting = false;
|
||||
|
||||
// ── Paths ──────────────────────────────────────────────────────────
|
||||
|
||||
@@ -184,6 +186,10 @@ async function startBackend() {
|
||||
});
|
||||
}
|
||||
|
||||
// Store PID immediately
|
||||
backendPid = backendProcess.pid;
|
||||
log(`Backend PID: ${backendPid}`);
|
||||
|
||||
// Pipe backend output to log
|
||||
const backendLogFile = path.join(logDir, 'rfcp-backend.log');
|
||||
const backendLog = fs.createWriteStream(backendLogFile, { flags: 'w' });
|
||||
@@ -262,10 +268,15 @@ function createMainWindow() {
|
||||
titleBarStyle: process.platform === 'darwin' ? 'hiddenInset' : 'default',
|
||||
});
|
||||
|
||||
// Save window state on close
|
||||
// Save window state on close and trigger shutdown
|
||||
mainWindow.on('close', () => {
|
||||
const bounds = mainWindow.getBounds();
|
||||
store.set('windowState', bounds);
|
||||
try {
|
||||
const bounds = mainWindow.getBounds();
|
||||
store.set('windowState', bounds);
|
||||
} catch (_e) {}
|
||||
log('Main window closing — killing backend');
|
||||
isQuitting = true;
|
||||
killBackend();
|
||||
});
|
||||
|
||||
// Load frontend
|
||||
@@ -309,28 +320,33 @@ function createMainWindow() {
|
||||
// ── Backend cleanup ───────────────────────────────────────────────
|
||||
|
||||
function killBackend() {
|
||||
if (!backendProcess) return;
|
||||
const pid = backendPid || backendProcess?.pid;
|
||||
if (!pid) return;
|
||||
|
||||
const pid = backendProcess.pid;
|
||||
log(`Killing backend (PID ${pid})...`);
|
||||
|
||||
try {
|
||||
if (process.platform === 'win32') {
|
||||
// Windows: taskkill with /T (tree) to kill child processes too
|
||||
execSync(`taskkill /f /t /pid ${pid}`, { stdio: 'ignore' });
|
||||
// Windows: taskkill with /F (force) /T (tree — kills child processes too)
|
||||
execSync(`taskkill /F /T /PID ${pid}`, { stdio: 'ignore' });
|
||||
} else {
|
||||
// Unix: kill process group
|
||||
process.kill(-pid, 'SIGTERM');
|
||||
try {
|
||||
process.kill(-pid, 'SIGTERM');
|
||||
} catch (_e) {
|
||||
process.kill(pid, 'SIGTERM');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Fallback: try normal kill
|
||||
// Fallback: try normal kill via process handle
|
||||
try {
|
||||
backendProcess.kill('SIGKILL');
|
||||
backendProcess?.kill('SIGKILL');
|
||||
} catch (_e2) {
|
||||
// Already dead
|
||||
// Already dead — that's fine
|
||||
}
|
||||
}
|
||||
|
||||
backendPid = null;
|
||||
backendProcess = null;
|
||||
log('Backend killed');
|
||||
}
|
||||
@@ -365,6 +381,8 @@ app.whenReady().then(async () => {
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
log('Event: window-all-closed');
|
||||
isQuitting = true;
|
||||
killBackend();
|
||||
|
||||
if (process.platform !== 'darwin') {
|
||||
@@ -379,14 +397,36 @@ app.on('activate', () => {
|
||||
});
|
||||
|
||||
app.on('before-quit', () => {
|
||||
log('Event: before-quit');
|
||||
isQuitting = true;
|
||||
killBackend();
|
||||
});
|
||||
|
||||
app.on('will-quit', () => {
|
||||
log('Event: will-quit');
|
||||
killBackend();
|
||||
|
||||
if (backendLogStream) {
|
||||
backendLogStream.end();
|
||||
try { backendLogStream.end(); } catch (_e) {}
|
||||
backendLogStream = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Last resort: ensure backend is killed when Node process exits
|
||||
process.on('exit', () => {
|
||||
if (backendPid) {
|
||||
try {
|
||||
if (process.platform === 'win32') {
|
||||
execSync(`taskkill /F /T /PID ${backendPid}`, { stdio: 'ignore' });
|
||||
} else {
|
||||
process.kill(backendPid, 'SIGKILL');
|
||||
}
|
||||
} catch (_e) {
|
||||
// Best effort
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ── IPC Handlers ───────────────────────────────────────────────────
|
||||
|
||||
ipcMain.handle('get-data-path', () => getDataPath());
|
||||
|
||||
Reference in New Issue
Block a user