mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
fix(search): publish capped results without waiting for process exit (#34861)
* fix(search): publish capped content results before process exit * test(search): drop duplicate queued kill-error variant --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
@@ -28,6 +28,8 @@ import { stopBundledRipgrep } from './bundled-ripgrep-stop'
|
||||
// NTFS permits POSIX-created names/types Windows rg cannot open (1/2/1920); skip them without truncating the search.
|
||||
const WINDOWS_UNOPENABLE_PATH_OS_ERRORS: ReadonlySet<number> = new Set([1, 2, 1920])
|
||||
|
||||
function ignoreCompletedSearchTerminationError(): void {}
|
||||
|
||||
export function runBundledRipgrepTextSearch({
|
||||
options,
|
||||
rootPath,
|
||||
@@ -110,10 +112,7 @@ export function runBundledRipgrepTextSearch({
|
||||
}
|
||||
const rejectUnavailable = (): void => finish(Promise.reject(bundledRipgrepUnavailableError()))
|
||||
const processLine = (line: string): void => {
|
||||
const verdict = ingestRgJsonLine(line, resultRootPath, acc, maxResults, transformAbsPath)
|
||||
if (verdict === 'stop' && child) {
|
||||
stopBundledRipgrep(child, Boolean(wslDistroForOutput))
|
||||
}
|
||||
ingestRgJsonLine(line, resultRootPath, acc, maxResults, transformAbsPath)
|
||||
}
|
||||
|
||||
let nextChild: ReturnType<typeof spawnBundledRipgrep>
|
||||
@@ -135,12 +134,14 @@ export function runBundledRipgrepTextSearch({
|
||||
releaseChild = onSpawn(nextChild)
|
||||
|
||||
const handleStdoutData = (chunk: string): void => {
|
||||
if (!lines.push(chunk, processLine)) {
|
||||
const withinLineLimit = lines.push(chunk, processLine)
|
||||
if (!withinLineLimit || acc.totalMatches >= maxResults) {
|
||||
acc.truncated = true
|
||||
child?.once('error', ignoreCompletedSearchTerminationError)
|
||||
resolveOnce()
|
||||
if (child) {
|
||||
stopBundledRipgrep(child, Boolean(wslDistroForOutput))
|
||||
}
|
||||
resolveOnce()
|
||||
}
|
||||
}
|
||||
const handleStderrData = (chunk: Buffer): void => {
|
||||
|
||||
@@ -168,6 +168,57 @@ describe('RuntimeFileCommands', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it.each(['ignored', 'erroring'] as const)(
|
||||
'publishes capped results and detaches when termination is %s',
|
||||
async (termination) => {
|
||||
const { commands } = createRuntimeFileCommands()
|
||||
const child = createRuntimeSearchChild()
|
||||
if (termination === 'erroring') {
|
||||
child.kill.mockImplementation(() => {
|
||||
child.emit('error', Object.assign(new Error('kill EPERM'), { code: 'EPERM' }))
|
||||
return false
|
||||
})
|
||||
}
|
||||
resolveAuthorizedPathMock.mockResolvedValue('/repo')
|
||||
wslAwareSpawnMock.mockReturnValue(child)
|
||||
const resultPromise = commands.searchRuntimeFiles('id:wt-1', {
|
||||
query: 'needle',
|
||||
maxResults: 2
|
||||
})
|
||||
let settled = false
|
||||
void resultPromise.then(() => {
|
||||
settled = true
|
||||
})
|
||||
await flushRuntimeSearchMicrotasks()
|
||||
const record = JSON.stringify({
|
||||
type: 'match',
|
||||
data: {
|
||||
path: { text: './example.txt' },
|
||||
lines: { text: 'needle needle\n' },
|
||||
line_number: 1,
|
||||
submatches: [
|
||||
{ start: 0, end: 6 },
|
||||
{ start: 7, end: 13 }
|
||||
]
|
||||
}
|
||||
})
|
||||
expect(() => child.stdout.emit('data', `${record}\n{"type":"match"`)).not.toThrow()
|
||||
await flushRuntimeSearchMicrotasks()
|
||||
|
||||
expect(settled).toBe(true)
|
||||
await expect(resultPromise).resolves.toMatchObject({
|
||||
totalMatches: 2,
|
||||
truncated: true,
|
||||
files: [{ matches: [{ column: 1 }, { column: 8 }] }]
|
||||
})
|
||||
expect(child.kill).toHaveBeenCalledOnce()
|
||||
expect(child.stdout.listenerCount('data')).toBe(0)
|
||||
expect(child.stderr.listenerCount('data')).toBe(0)
|
||||
expect(child.listenerCount('close')).toBe(0)
|
||||
expect(vi.getTimerCount()).toBe(0)
|
||||
}
|
||||
)
|
||||
|
||||
it.each(['error-first', 'close-first'] as const)(
|
||||
'rejects with the bundled-ripgrep error when runtime rg native launch failure is %s',
|
||||
async (order) => {
|
||||
|
||||
Reference in New Issue
Block a user