mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-09-05 15:38:46 +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:
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
"module": "./main/index.mjs",
|
"module": "./main/index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"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",
|
"author": "geekgeekrun",
|
||||||
"license": "ISC",
|
"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
|
||||||
|
})()
|
||||||
+38
-27
@@ -10,6 +10,23 @@ import { get__dirname } from '@geekgeekrun/utils/legacy-path.mjs';
|
|||||||
import JSON5 from 'json5'
|
import JSON5 from 'json5'
|
||||||
import { readConfigFile, readStorageFile } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
import { readConfigFile, readStorageFile } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
||||||
import { sleep } from '@geekgeekrun/utils/sleep.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 bossCookies = readStorageFile('boss-cookies.json')
|
||||||
const { groupRobotAccessToken: dingTalkAccessToken } = readConfigFile('dingtalk.json')
|
const { groupRobotAccessToken: dingTalkAccessToken } = readConfigFile('dingtalk.json')
|
||||||
|
|
||||||
@@ -17,11 +34,6 @@ const initPlugins = (hooks) => {
|
|||||||
new DingtalkPlugin(dingTalkAccessToken).apply(hooks)
|
new DingtalkPlugin(dingTalkAccessToken).apply(hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
const AUTO_CHAT_ERROR_EXIT_CODE = {
|
|
||||||
COOKIE_INVALID: 81,
|
|
||||||
LOGIN_STATUS_INVALID: 82
|
|
||||||
}
|
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
if (!bossCookies?.length) {
|
if (!bossCookies?.length) {
|
||||||
console.error('There is no cookies. You can save a copy with EditThisCookie extension.')
|
console.error('There is no cookies. You can save a copy with EditThisCookie extension.')
|
||||||
@@ -42,30 +54,29 @@ const main = async () => {
|
|||||||
try {
|
try {
|
||||||
await mainLoop(hooks)
|
await mainLoop(hooks)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof Error && err.message.includes('LOGIN_STATUS_INVALID')) {
|
if (err instanceof Error) {
|
||||||
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.LOGIN_STATUS_INVALID)
|
if (err.message.includes('LOGIN_STATUS_INVALID')) {
|
||||||
break
|
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) => {
|
(async () => {
|
||||||
closeBrowserWindow()
|
try {
|
||||||
console.error('error')
|
await main()
|
||||||
console.error(error)
|
} catch {}
|
||||||
await sleep(3000)
|
})()
|
||||||
|
|
||||||
main()
|
|
||||||
})
|
|
||||||
|
|
||||||
process.on('unhandledRejection', async (reason, promise) => {
|
|
||||||
closeBrowserWindow()
|
|
||||||
console.error('unhandledRejection')
|
|
||||||
console.error(reason, promise)
|
|
||||||
await sleep(3000)
|
|
||||||
|
|
||||||
main()
|
|
||||||
});
|
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
"module": "./index.mjs",
|
"module": "./index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"start": "node ./daemon-main.mjs",
|
||||||
|
"start:bare": "node ./main.mjs"
|
||||||
},
|
},
|
||||||
"author": "geekgeekrun",
|
"author": "geekgeekrun",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|||||||
Reference in New Issue
Block a user