diff --git a/resources/js/electron-plugin/dist/index.js b/resources/js/electron-plugin/dist/index.js index c854028..42d2192 100644 --- a/resources/js/electron-plugin/dist/index.js +++ b/resources/js/electron-plugin/dist/index.js @@ -11,7 +11,7 @@ import { app, session, powerMonitor } from "electron"; import { initialize } from "@electron/remote/main/index.js"; import state from "./server/state.js"; import { electronApp, optimizer } from "@electron-toolkit/utils"; -import { retrieveNativePHPConfig, retrievePhpIniSettings, runScheduler, startAPI, startPhpApp, } from "./server/index.js"; +import { retrieveNativePHPConfig, retrievePhpIniSettings, runScheduler, killScheduler, startAPI, startPhpApp, } from "./server/index.js"; import { notifyLaravel } from "./server/utils.js"; import { resolve } from "path"; import { stopAllProcesses } from "./server/api/childProcess.js"; @@ -22,8 +22,8 @@ const { autoUpdater } = electronUpdater; class NativePHP { constructor() { this.processes = []; - this.schedulerInterval = undefined; this.mainWindow = null; + this.schedulerInterval = undefined; } bootstrap(app, icon, phpBinary, cert) { initialize(); @@ -192,6 +192,7 @@ class NativePHP { clearInterval(this.schedulerInterval); this.schedulerInterval = null; } + killScheduler(); } startScheduler() { const now = new Date(); @@ -206,9 +207,14 @@ class NativePHP { }, delay); } killChildProcesses() { + this.stopScheduler(); this.processes .filter((p) => p !== undefined) .forEach((process) => { + if (!process || !process.pid) + return; + if (process.killed && process.exitCode !== null) + return; try { killSync(process.pid, 'SIGTERM', true); ps.kill(process.pid); diff --git a/resources/js/electron-plugin/dist/server/index.js b/resources/js/electron-plugin/dist/server/index.js index 0373af8..7a1f943 100644 --- a/resources/js/electron-plugin/dist/server/index.js +++ b/resources/js/electron-plugin/dist/server/index.js @@ -11,6 +11,7 @@ import startAPIServer from "./api.js"; import { retrieveNativePHPConfig, retrievePhpIniSettings, serveApp, startScheduler, } from "./php.js"; import { appendCookie } from "./utils.js"; import state from "./state.js"; +let schedulerProcess = null; export function startPhpApp() { return __awaiter(this, void 0, void 0, function* () { const result = yield serveApp(state.randomSecret, state.electronApiPort, state.phpIni); @@ -20,7 +21,14 @@ export function startPhpApp() { }); } export function runScheduler() { - startScheduler(state.randomSecret, state.electronApiPort, state.phpIni); + killScheduler(); + schedulerProcess = startScheduler(state.randomSecret, state.electronApiPort, state.phpIni); +} +export function killScheduler() { + if (schedulerProcess && !schedulerProcess.killed) { + schedulerProcess.kill(); + schedulerProcess = null; + } } export function startAPI() { return startAPIServer(state.randomSecret); diff --git a/resources/js/electron-plugin/src/index.ts b/resources/js/electron-plugin/src/index.ts index 6575703..a1a8ee9 100644 --- a/resources/js/electron-plugin/src/index.ts +++ b/resources/js/electron-plugin/src/index.ts @@ -1,5 +1,6 @@ import CrossProcessExports from "electron"; import { app, session, powerMonitor } from "electron"; +import { ChildProcessWithoutNullStreams } from "child_process"; import { initialize } from "@electron/remote/main/index.js"; import state from "./server/state.js"; import { electronApp, optimizer } from "@electron-toolkit/utils"; @@ -7,6 +8,7 @@ import { retrieveNativePHPConfig, retrievePhpIniSettings, runScheduler, + killScheduler, startAPI, startPhpApp, } from "./server/index.js"; @@ -21,9 +23,9 @@ import electronUpdater from 'electron-updater'; const { autoUpdater } = electronUpdater; class NativePHP { - processes = []; - schedulerInterval = undefined; + processes: ChildProcessWithoutNullStreams[] = []; mainWindow = null; + schedulerInterval = undefined; public bootstrap( app: CrossProcessExports.App, @@ -244,12 +246,13 @@ class NativePHP { } - private stopScheduler() { - if (this.schedulerInterval) { - clearInterval(this.schedulerInterval); - this.schedulerInterval = null; - } - } + private stopScheduler() { + if (this.schedulerInterval) { + clearInterval(this.schedulerInterval); + this.schedulerInterval = null; + } + killScheduler(); + } private startScheduler() { const now = new Date(); @@ -270,16 +273,23 @@ class NativePHP { } private killChildProcesses() { + this.stopScheduler(); + this.processes .filter((p) => p !== undefined) .forEach((process) => { + if (!process || !process.pid) return; + if (process.killed && process.exitCode !== null) return; + try { // @ts-ignore killSync(process.pid, 'SIGTERM', true); // Kill tree ps.kill(process.pid); // Sometimes does not kill the subprocess of php server + } catch (err) { console.error(err); } + }); } } diff --git a/resources/js/electron-plugin/src/server/api/childProcess.ts b/resources/js/electron-plugin/src/server/api/childProcess.ts index c7fd6b5..0d4421c 100644 --- a/resources/js/electron-plugin/src/server/api/childProcess.ts +++ b/resources/js/electron-plugin/src/server/api/childProcess.ts @@ -1,5 +1,5 @@ import express from 'express'; -import {utilityProcess} from 'electron'; +import {utilityProcess, UtilityProcess} from 'electron'; import state from '../state.js'; import {notifyLaravel} from "../utils.js"; import {getAppPath, getDefaultEnvironmentVariables, getDefaultPhpIniSettings, runningSecureBuild} from "../php.js"; @@ -207,7 +207,7 @@ export function stopAllProcesses() { } } -function getProcess(alias) { +function getProcess(alias: string): UtilityProcess | undefined { return state.processes[alias]?.proc; } diff --git a/resources/js/electron-plugin/src/server/index.ts b/resources/js/electron-plugin/src/server/index.ts index 4ef933b..58be7df 100644 --- a/resources/js/electron-plugin/src/server/index.ts +++ b/resources/js/electron-plugin/src/server/index.ts @@ -7,6 +7,9 @@ import { } from "./php.js"; import { appendCookie } from "./utils.js"; import state from "./state.js"; +import { ChildProcess } from "child_process"; + +let schedulerProcess: ChildProcess | null = null; export async function startPhpApp() { const result = await serveApp( @@ -23,7 +26,15 @@ export async function startPhpApp() { } export function runScheduler() { - startScheduler(state.randomSecret, state.electronApiPort, state.phpIni); + killScheduler(); + schedulerProcess = startScheduler(state.randomSecret, state.electronApiPort, state.phpIni); +} + +export function killScheduler() { + if (schedulerProcess && !schedulerProcess.killed) { + schedulerProcess.kill(); + schedulerProcess = null; + } } export function startAPI(): Promise {