mirror of
https://github.com/pockethost/pockethost.git
synced 2025-07-03 03:12:29 +00:00
enh: process killing enhancements
This commit is contained in:
parent
63b046a1e8
commit
671a69f943
@ -159,8 +159,8 @@ export const instanceService = mkSingleton(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
shutdownManager.add(() => {
|
shutdownManager.add(async () => {
|
||||||
const res = childProcess.kill()
|
const res = await childProcess.kill()
|
||||||
if (!res) {
|
if (!res) {
|
||||||
error(`Expected child process to exit gracefully but got ${res}`)
|
error(`Expected child process to exit gracefully but got ${res}`)
|
||||||
}
|
}
|
||||||
@ -176,13 +176,6 @@ export const instanceService = mkSingleton(
|
|||||||
assertTruthy(pid, `Expected PID here but got ${pid}`)
|
assertTruthy(pid, `Expected PID here but got ${pid}`)
|
||||||
dbg(`PocketBase instance PID: ${pid}`)
|
dbg(`PocketBase instance PID: ${pid}`)
|
||||||
|
|
||||||
if (!instance.isBackupAllowed) {
|
|
||||||
dbg(`Backups are now allowed`)
|
|
||||||
await clientLimiter.schedule(() =>
|
|
||||||
client.updateInstance(instance.id, { isBackupAllowed: true })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const invocation = await clientLimiter.schedule(() =>
|
const invocation = await clientLimiter.schedule(() =>
|
||||||
client.createInvocation(instance, pid)
|
client.createInvocation(instance, pid)
|
||||||
)
|
)
|
||||||
|
@ -31,7 +31,11 @@ export type SpawnConfig = {
|
|||||||
version?: string
|
version?: string
|
||||||
port?: number
|
port?: number
|
||||||
isMothership?: boolean
|
isMothership?: boolean
|
||||||
onUnexpectedStop?: (code: number | null) => void
|
onUnexpectedStop?: (
|
||||||
|
code: number | null,
|
||||||
|
stdout: string[],
|
||||||
|
stderr: string[]
|
||||||
|
) => void
|
||||||
}
|
}
|
||||||
export type PocketbaseServiceApi = AsyncReturnType<
|
export type PocketbaseServiceApi = AsyncReturnType<
|
||||||
typeof createPocketbaseService
|
typeof createPocketbaseService
|
||||||
@ -45,7 +49,7 @@ export type PocketbaseServiceConfig = SingletonBaseConfig & {
|
|||||||
export type PocketbaseProcess = {
|
export type PocketbaseProcess = {
|
||||||
url: string
|
url: string
|
||||||
pid: number | undefined
|
pid: number | undefined
|
||||||
kill: () => boolean
|
kill: () => Promise<boolean>
|
||||||
exited: Promise<number | null>
|
exited: Promise<number | null>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +63,15 @@ export type Release = {
|
|||||||
}
|
}
|
||||||
export type Releases = Release[]
|
export type Releases = Release[]
|
||||||
|
|
||||||
|
function pidIsRunning(pid: number) {
|
||||||
|
try {
|
||||||
|
process.kill(pid, 0)
|
||||||
|
return true
|
||||||
|
} catch (e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const createPocketbaseService = async (
|
export const createPocketbaseService = async (
|
||||||
config: PocketbaseServiceConfig
|
config: PocketbaseServiceConfig
|
||||||
) => {
|
) => {
|
||||||
@ -184,14 +197,22 @@ export const createPocketbaseService = async (
|
|||||||
|
|
||||||
dbg(`Spawning ${slug}`, { bin, args, cli: [bin, ...args].join(' ') })
|
dbg(`Spawning ${slug}`, { bin, args, cli: [bin, ...args].join(' ') })
|
||||||
const ls = spawn(bin, args)
|
const ls = spawn(bin, args)
|
||||||
cm.add(() => ls.kill())
|
cm.add(() => {
|
||||||
|
ls.kill()
|
||||||
ls.stdout.on('data', (data) => {
|
|
||||||
dbg(`${slug} stdout: ${data}`)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
ls.stderr.on('data', (data) => {
|
const stdout: string[] = []
|
||||||
error(`${slug} stderr: ${data}`)
|
ls.stdout.on('data', (data: Buffer) => {
|
||||||
|
dbg(`${slug} stdout: ${data}`)
|
||||||
|
stdout.push(data.toString())
|
||||||
|
if (stdout.length > 100) stdout.pop()
|
||||||
|
})
|
||||||
|
|
||||||
|
const stderr: string[] = []
|
||||||
|
ls.stderr.on('data', (data: Buffer) => {
|
||||||
|
warn(`${slug} stderr: ${data}`)
|
||||||
|
stderr.push(data.toString())
|
||||||
|
if (stderr.length > 100) stderr.pop()
|
||||||
})
|
})
|
||||||
|
|
||||||
ls.on('close', (code) => {
|
ls.on('close', (code) => {
|
||||||
@ -202,7 +223,9 @@ export const createPocketbaseService = async (
|
|||||||
ls.on('exit', (code) => {
|
ls.on('exit', (code) => {
|
||||||
dbg(`${slug} exited with code ${code}`)
|
dbg(`${slug} exited with code ${code}`)
|
||||||
isRunning = false
|
isRunning = false
|
||||||
if (code) onUnexpectedStop?.(code)
|
if (code || stderr.length > 0) {
|
||||||
|
onUnexpectedStop?.(code, stdout, stderr)
|
||||||
|
}
|
||||||
resolve(code)
|
resolve(code)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -219,7 +242,36 @@ export const createPocketbaseService = async (
|
|||||||
url,
|
url,
|
||||||
exited,
|
exited,
|
||||||
pid: ls.pid,
|
pid: ls.pid,
|
||||||
kill: () => ls.kill(),
|
kill: async () => {
|
||||||
|
const { pid } = ls
|
||||||
|
if (!pid) {
|
||||||
|
throw new Error(
|
||||||
|
`Attempt to kill a PocketBase process that was never running.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const p = new Promise<boolean>((resolve, reject) => {
|
||||||
|
let cid: NodeJS.Timeout
|
||||||
|
const tid = setTimeout(() => {
|
||||||
|
clearTimeout(cid)
|
||||||
|
reject(new Error(`Timeout waiting for pid:${pid} to die`))
|
||||||
|
}, 1000)
|
||||||
|
const _check = () => {
|
||||||
|
dbg(`Checking to see if pid:${pid} is running`)
|
||||||
|
if (pidIsRunning(pid)) {
|
||||||
|
dbg(`pid:${pid} is still running`)
|
||||||
|
ls.kill()
|
||||||
|
cid = setTimeout(_check, 50)
|
||||||
|
} else {
|
||||||
|
dbg(`pid:${pid} is not running`)
|
||||||
|
clearTimeout(tid)
|
||||||
|
|
||||||
|
resolve(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_check()
|
||||||
|
})
|
||||||
|
return p
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return api
|
return api
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user