mirror of
https://github.com/stablyai/orca.git
synced 2026-10-28 16:02:55 +00:00
fix(daemon): enforce stderr retention bound
This commit is contained in:
@@ -46,6 +46,33 @@ describe('observeDaemonChildExit', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('retains only the configured bytes from an oversized stderr chunk', () => {
|
||||
const child = createChild()
|
||||
const onExit = vi.fn()
|
||||
const observer = observeDaemonChildExit(child, onExit, 8)
|
||||
|
||||
observer.markReady()
|
||||
child.stderr.write(Buffer.from(`${'x'.repeat(1024 * 1024)}FATAL`))
|
||||
child.emit('exit', 134, null)
|
||||
child.stderr.emit('end')
|
||||
|
||||
expect(onExit).toHaveBeenCalledWith(expect.objectContaining({ stderrTail: 'xxxFATAL' }))
|
||||
})
|
||||
|
||||
it('reports once when stderr closes before the child exits', () => {
|
||||
const child = createChild()
|
||||
const onExit = vi.fn()
|
||||
const observer = observeDaemonChildExit(child, onExit)
|
||||
|
||||
observer.markReady()
|
||||
child.stderr.emit('close')
|
||||
child.emit('exit', 134, null)
|
||||
child.emit('exit', 134, null)
|
||||
|
||||
expect(onExit).toHaveBeenCalledOnce()
|
||||
expect(onExit).toHaveBeenCalledWith(expect.objectContaining({ stderrTail: '' }))
|
||||
})
|
||||
|
||||
it('swallows stderr errors after process exit while awaiting drain', () => {
|
||||
const child = createChild()
|
||||
const onExit = vi.fn()
|
||||
|
||||
@@ -28,6 +28,17 @@ export type DaemonChildExitObserver = {
|
||||
stop(options?: { destroyStderr?: boolean }): void
|
||||
}
|
||||
|
||||
function appendStderrTail(current: Buffer, chunk: Buffer, maxBytes: number): Buffer {
|
||||
if (maxBytes <= 0) {
|
||||
return Buffer.alloc(0)
|
||||
}
|
||||
if (chunk.length >= maxBytes) {
|
||||
return Buffer.from(chunk.subarray(-maxBytes))
|
||||
}
|
||||
const currentBytes = Math.min(current.length, maxBytes - chunk.length)
|
||||
return Buffer.concat([current.subarray(-currentBytes), chunk], currentBytes + chunk.length)
|
||||
}
|
||||
|
||||
export function observeDaemonChildExit(
|
||||
child: ObservableDaemonChild,
|
||||
recordExit: (observation: DaemonChildExitObservation) => void,
|
||||
@@ -42,7 +53,7 @@ export function observeDaemonChildExit(
|
||||
|
||||
const onStderr = (chunk: Buffer | string): void => {
|
||||
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)
|
||||
stderrTail = Buffer.concat([stderrTail, bytes]).subarray(-maxStderrBytes)
|
||||
stderrTail = appendStderrTail(stderrTail, bytes, maxStderrBytes)
|
||||
}
|
||||
const onStderrError = (): void => {}
|
||||
const finalizeExit = (): void => {
|
||||
|
||||
Reference in New Issue
Block a user