mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-06-30 03:41:40 +08:00
move the core logic of run core to child process, and rerun run child process in daemon process when uncaught error makes process terminated.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
"module": "./main/index.mjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node ./packages/run-core-of-geek-auto-start-chat-with-boss/index.mjs"
|
||||
"start": "node ./packages/run-core-of-geek-auto-start-chat-with-boss/daemon-main.mjs"
|
||||
},
|
||||
"author": "geekgeekrun",
|
||||
"license": "ISC",
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import path from 'node:path'
|
||||
import * as url from 'url'
|
||||
import { sleep } from '@geekgeekrun/utils/sleep.mjs';
|
||||
import childProcess from 'node:child_process';
|
||||
import { AUTO_CHAT_ERROR_EXIT_CODE } from './enums.mjs'
|
||||
|
||||
const rerunInterval = (() => {
|
||||
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
||||
if (isNaN(v)) {
|
||||
v = 3000
|
||||
}
|
||||
|
||||
return v
|
||||
})()
|
||||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
||||
function runWithDaemon () {
|
||||
const subProcessOfCore = childProcess.spawn(
|
||||
`node`,
|
||||
[path.join(
|
||||
__dirname,
|
||||
'main.mjs'
|
||||
)],
|
||||
{
|
||||
stdio: ['inherit', 'inherit', 'inherit', 'pipe', 'ipc'],
|
||||
env: {
|
||||
...process.env,
|
||||
MAIN_BOSSGEEKGO_RERUN_INTERVAL: rerunInterval
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
subProcessOfCore.once(
|
||||
'exit',
|
||||
async (exitCode) => {
|
||||
if (
|
||||
[
|
||||
...Object.values(AUTO_CHAT_ERROR_EXIT_CODE)
|
||||
].filter(it => typeof it === 'number').includes(exitCode)
|
||||
) {
|
||||
console.log(`[Run core daemon] Child process exit with reason ${AUTO_CHAT_ERROR_EXIT_CODE[exitCode]}.`)
|
||||
process.exit(exitCode)
|
||||
return
|
||||
}
|
||||
console.log(`[Run core daemon] Child process exit with code ${exitCode}, an internal may not be caught, and will be restarted in ${rerunInterval}ms.`)
|
||||
await sleep(rerunInterval)
|
||||
runWithDaemon()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
runWithDaemon()
|
||||
@@ -0,0 +1,16 @@
|
||||
export const AUTO_CHAT_ERROR_EXIT_CODE = (() => {
|
||||
const enums = {
|
||||
NORMAL: 0,
|
||||
COOKIE_INVALID: 81,
|
||||
LOGIN_STATUS_INVALID: 82,
|
||||
ERR_INTERNET_DISCONNECTED: 83,
|
||||
ACCESS_IS_DENIED: 84
|
||||
}
|
||||
const kvList = Object.entries(enums)
|
||||
|
||||
kvList.forEach(([k, v]) => {
|
||||
enums[v] = k
|
||||
})
|
||||
|
||||
return enums
|
||||
})()
|
||||
@@ -10,6 +10,23 @@ import { get__dirname } from '@geekgeekrun/utils/legacy-path.mjs';
|
||||
import JSON5 from 'json5'
|
||||
import { readConfigFile, readStorageFile } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
||||
import { sleep } from '@geekgeekrun/utils/sleep.mjs'
|
||||
import {
|
||||
AUTO_CHAT_ERROR_EXIT_CODE
|
||||
} from './enums.mjs'
|
||||
|
||||
const rerunInterval = (() => {
|
||||
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
||||
if (isNaN(v)) {
|
||||
v = 3000
|
||||
}
|
||||
|
||||
return v
|
||||
})()
|
||||
|
||||
process.on('disconnect', () => {
|
||||
process.exit()
|
||||
})
|
||||
|
||||
const bossCookies = readStorageFile('boss-cookies.json')
|
||||
const { groupRobotAccessToken: dingTalkAccessToken } = readConfigFile('dingtalk.json')
|
||||
|
||||
@@ -17,11 +34,6 @@ const initPlugins = (hooks) => {
|
||||
new DingtalkPlugin(dingTalkAccessToken).apply(hooks)
|
||||
}
|
||||
|
||||
const AUTO_CHAT_ERROR_EXIT_CODE = {
|
||||
COOKIE_INVALID: 81,
|
||||
LOGIN_STATUS_INVALID: 82
|
||||
}
|
||||
|
||||
const main = async () => {
|
||||
if (!bossCookies?.length) {
|
||||
console.error('There is no cookies. You can save a copy with EditThisCookie extension.')
|
||||
@@ -42,30 +54,29 @@ const main = async () => {
|
||||
try {
|
||||
await mainLoop(hooks)
|
||||
} catch (err) {
|
||||
if (err instanceof Error && err.message.includes('LOGIN_STATUS_INVALID')) {
|
||||
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.LOGIN_STATUS_INVALID)
|
||||
break
|
||||
if (err instanceof Error) {
|
||||
if (err.message.includes('LOGIN_STATUS_INVALID')) {
|
||||
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.LOGIN_STATUS_INVALID)
|
||||
break
|
||||
}
|
||||
if (err.message.includes('ERR_INTERNET_DISCONNECTED')) {
|
||||
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.ERR_INTERNET_DISCONNECTED)
|
||||
break
|
||||
}
|
||||
if (err.message.includes('ACCESS_IS_DENIED')) {
|
||||
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.ACCESS_IS_DENIED)
|
||||
break
|
||||
}
|
||||
}
|
||||
await sleep(3000)
|
||||
console.error(err)
|
||||
console.log(`[Run core main] An internal is caught, and browser will be restarted in ${rerunInterval}ms.`)
|
||||
await sleep(rerunInterval)
|
||||
}
|
||||
}
|
||||
}
|
||||
main()
|
||||
|
||||
process.on('error', async (error) => {
|
||||
closeBrowserWindow()
|
||||
console.error('error')
|
||||
console.error(error)
|
||||
await sleep(3000)
|
||||
|
||||
main()
|
||||
})
|
||||
|
||||
process.on('unhandledRejection', async (reason, promise) => {
|
||||
closeBrowserWindow()
|
||||
console.error('unhandledRejection')
|
||||
console.error(reason, promise)
|
||||
await sleep(3000)
|
||||
|
||||
main()
|
||||
});
|
||||
(async () => {
|
||||
try {
|
||||
await main()
|
||||
} catch {}
|
||||
})()
|
||||
@@ -6,6 +6,8 @@
|
||||
"module": "./index.mjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node ./daemon-main.mjs",
|
||||
"start:bare": "node ./main.mjs"
|
||||
},
|
||||
"author": "geekgeekrun",
|
||||
"license": "ISC",
|
||||
|
||||
Reference in New Issue
Block a user