diff --git a/packages/ui/src/main/flow/GEEK_AUTO_START_CHAT_WITH_BOSS_DAEMON/index.ts b/packages/ui/src/main/flow/GEEK_AUTO_START_CHAT_WITH_BOSS_DAEMON/index.ts index 53a6801..4cee520 100644 --- a/packages/ui/src/main/flow/GEEK_AUTO_START_CHAT_WITH_BOSS_DAEMON/index.ts +++ b/packages/ui/src/main/flow/GEEK_AUTO_START_CHAT_WITH_BOSS_DAEMON/index.ts @@ -11,6 +11,7 @@ import { initDb } from '@geekgeekrun/sqlite-plugin' import { getPublicDbFilePath } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs' import { AutoStartChatRunRecord } from '@geekgeekrun/sqlite-plugin/dist/entity/AutoStartChatRunRecord' import minimist from 'minimist' +import attachListenerForKillSelfOnParentExited from '../../utils/attachListenerForKillSelfOnParentExited' const rerunInterval = (() => { let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL) @@ -20,7 +21,7 @@ const rerunInterval = (() => { return v })() -function runWithDaemon({ runRecordId, runMode }) { +function runWithDaemon({ runRecordId, runMode, parentProcessPipe }) { const subProcessOfCore = childProcess.spawn( process.argv[0], [...process.argv.slice(1), `--run-record-id=${runRecordId}`], @@ -36,11 +37,11 @@ function runWithDaemon({ runRecordId, runMode }) { subProcessOfCore!.stdio[3]!.pipe(JSONStream.parse()).on('data', async (raw) => { const data = raw switch (data.type) { - case 'AUTO_START_CHAT_MAIN_PROCESS_STARTUP': { + case 'GEEK_AUTO_START_CHAT_WITH_BOSS_STARTED': { pipeWriteRegardlessError( - subProcessOfCore!.stdio[3]! as WriteStream, + parentProcessPipe as WriteStream, JSON.stringify({ - type: 'GEEK_AUTO_START_CHAT_CAN_BE_RUN' + type: data.type }) ) break @@ -67,23 +68,10 @@ function runWithDaemon({ runRecordId, runMode }) { `[Run core daemon] Child process exit with code ${exitCode}, an internal error may not be caught, and will be restarted in ${rerunInterval}ms.` ) await sleep(rerunInterval) - runWithDaemon({ runRecordId, runMode }) + runWithDaemon({ runRecordId, runMode, parentProcessPipe }) }) } -// suicide timer for parent and child process don't have any communication after child process spawned. -let suicideTimer: NodeJS.Timeout | null = null -const setSuicideTimer = () => - (suicideTimer = setTimeout(() => { - app.exit(AUTO_CHAT_ERROR_EXIT_CODE.AUTO_START_CHAT_DAEMON_PROCESS_SUICIDE) - }, 10000)) -const clearSuicideTimer = () => { - if (suicideTimer) { - clearTimeout(suicideTimer) - } - suicideTimer = null -} - export async function runAutoChatWithDaemon() { const commandlineArgs = minimist(process.argv.slice(2)) if (!['geekAutoStartWithBossMain'].includes(commandlineArgs['mode-to-daemon'])) { @@ -103,7 +91,6 @@ export async function runAutoChatWithDaemon() { process.on('disconnect', () => { app.exit() }) - setSuicideTimer() let pipe: null | fs.WriteStream = null try { @@ -116,27 +103,21 @@ export async function runAutoChatWithDaemon() { const disposePowerSaveBlocker = initPowerSaveBlocker() app.once('quit', disposePowerSaveBlocker) - const pipeForRead: fs.ReadStream = fs.createReadStream(null, { fd: 3 }) - const pipeForReadWithJsonParser = pipeForRead.pipe(JSONStream.parse()) - pipeForReadWithJsonParser?.on('data', async function waitForCanRun(data) { - if (data.type === 'GEEK_AUTO_START_CHAT_CAN_BE_RUN') { - pipeForReadWithJsonParser.off('data', waitForCanRun) - clearSuicideTimer() - // if don't call close, when kill child process, child process will ANR. - pipeForRead.close() - - const ds = await initDb(getPublicDbFilePath()) - const autoStartChatRunRecord = new AutoStartChatRunRecord() - autoStartChatRunRecord.date = new Date() - const autoStartChatRunRecordRepository = ds.getRepository(AutoStartChatRunRecord) - const result = await autoStartChatRunRecordRepository.save(autoStartChatRunRecord) - runWithDaemon({ runRecordId: result.id, runMode }) - } - }) process.on('SIGINT', () => { process.exit() }) + const ds = await initDb(getPublicDbFilePath()) + const autoStartChatRunRecord = new AutoStartChatRunRecord() + autoStartChatRunRecord.date = new Date() + const autoStartChatRunRecordRepository = ds.getRepository(AutoStartChatRunRecord) + const result = await autoStartChatRunRecordRepository.save(autoStartChatRunRecord) + runWithDaemon({ + runRecordId: result.id, + runMode: commandlineArgs['mode-to-daemon'], + parentProcessPipe: pipe + }) + pipeWriteRegardlessError( pipe, JSON.stringify({ @@ -146,3 +127,5 @@ export async function runAutoChatWithDaemon() { gtag('run_auto_chat_with_boss_daemon_ready') } + +attachListenerForKillSelfOnParentExited() diff --git a/packages/ui/src/main/flow/GEEK_AUTO_START_CHAT_WITH_BOSS_MAIN/index.ts b/packages/ui/src/main/flow/GEEK_AUTO_START_CHAT_WITH_BOSS_MAIN/index.ts index 4623e2e..ff3e2d2 100644 --- a/packages/ui/src/main/flow/GEEK_AUTO_START_CHAT_WITH_BOSS_MAIN/index.ts +++ b/packages/ui/src/main/flow/GEEK_AUTO_START_CHAT_WITH_BOSS_MAIN/index.ts @@ -11,7 +11,7 @@ import { pipeWriteRegardlessError } from '../utils/pipe' import { getAnyAvailablePuppeteerExecutable } from '../CHECK_AND_DOWNLOAD_DEPENDENCIES/utils/puppeteer-executable' import { sleep } from '@geekgeekrun/utils/sleep.mjs' import { AUTO_CHAT_ERROR_EXIT_CODE } from '../../../common/enums/auto-start-chat' -import * as JSONStream from 'JSONStream' +import attachListenerForKillSelfOnParentExited from '../../utils/attachListenerForKillSelfOnParentExited' import SqlitePluginModule from '@geekgeekrun/sqlite-plugin' import gtag from '../../utils/gtag' @@ -140,38 +140,8 @@ const runAutoChat = async () => { } } } -// suicide timer for parent and child process don't have any communication after child process spawned. -let suicideTimer: NodeJS.Timeout | null = null -const setSuicideTimer = () => - (suicideTimer = setTimeout(() => { - app.exit(AUTO_CHAT_ERROR_EXIT_CODE.AUTO_START_CHAT_MAIN_PROCESS_SUICIDE) - }, 10000)) -const clearSuicideTimer = () => { - if (suicideTimer) { - clearTimeout(suicideTimer) - } - suicideTimer = null -} export const waitForProcessHandShakeAndRunAutoChat = () => { - setSuicideTimer() - - const pipeForRead: fs.ReadStream = fs.createReadStream(null, { fd: 3 }) - pipeForRead.on('error', () => { - return - }) - const pipeForReadWithJsonParser = pipeForRead.pipe(JSONStream.parse()) - pipeForReadWithJsonParser?.on('data', function waitForCanRun(data) { - if (data.type === 'GEEK_AUTO_START_CHAT_CAN_BE_RUN') { - pipeForReadWithJsonParser.off('data', waitForCanRun) - clearSuicideTimer() - runAutoChat() - - // if don't call close, when kill child process, child process will ANR. - pipeForRead.close() - } - }) - let pipe: null | fs.WriteStream = null try { pipe = fs.createWriteStream(null, { fd: 3 }) @@ -179,10 +149,7 @@ export const waitForProcessHandShakeAndRunAutoChat = () => { console.error('pipe is not available') app.exit(1) } - pipeWriteRegardlessError( - pipe, - JSON.stringify({ - type: 'AUTO_START_CHAT_MAIN_PROCESS_STARTUP' - }) - ) + runAutoChat() } + +attachListenerForKillSelfOnParentExited() diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts index cb5d2af..6aa6bf5 100644 --- a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts @@ -117,14 +117,6 @@ export default function initIpc() { subProcessOfPuppeteer!.stdio[3]!.pipe(JSONStream.parse()).on('data', async (raw) => { const data = raw switch (data.type) { - case 'AUTO_START_CHAT_DAEMON_PROCESS_STARTUP': { - subProcessOfPuppeteer!.stdio[3]!.write( - JSON.stringify({ - type: 'GEEK_AUTO_START_CHAT_CAN_BE_RUN' - }) - ) - break - } case 'GEEK_AUTO_START_CHAT_WITH_BOSS_STARTED': { resolve(data) break