mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
perf: accelerate cancellable remote transcript line scanning (#20351)
* perf: search remote transcript newlines directly * fix: bound newline search by the yield window so cancellation stays observable A newline-free segment jumped straight to the next line break, skipping the character-count yield and its abort checks. Cap each jump at the yield window and yield there so a large single-line transcript still stops promptly. --------- Co-authored-by: Orca Worker <orca-worker@localhost> Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
co-authored by
Orca Worker
Neil
parent
411843f633
commit
fc81355fe1
@@ -0,0 +1,59 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { remoteSessionContentLines } from './remote-session-content-lines'
|
||||
|
||||
// Mirrors REMOTE_CONTENT_YIELD_CHAR_COUNT in the implementation.
|
||||
const YIELD_CHAR_COUNT = 256 * 1024
|
||||
|
||||
async function collect(content: string, signal: AbortSignal): Promise<string[]> {
|
||||
const lines: string[] = []
|
||||
for await (const line of remoteSessionContentLines(content, signal)) {
|
||||
lines.push(line)
|
||||
}
|
||||
return lines
|
||||
}
|
||||
|
||||
describe('remote session content lines', () => {
|
||||
it.each([
|
||||
['', ['']],
|
||||
['\n', ['', '']],
|
||||
['one\r\ntwo\n', ['one', 'two', '']],
|
||||
['one\rtwo\r', ['one\rtwo']],
|
||||
['x'.repeat(300_000), ['x'.repeat(300_000)]],
|
||||
[`${'x'.repeat(YIELD_CHAR_COUNT + 1)}\ny`, ['x'.repeat(YIELD_CHAR_COUNT + 1), 'y']],
|
||||
[`${'x'.repeat(YIELD_CHAR_COUNT)}\r\ny`, ['x'.repeat(YIELD_CHAR_COUNT), 'y']],
|
||||
[`${'x'.repeat(YIELD_CHAR_COUNT * 2)}\ny`, ['x'.repeat(YIELD_CHAR_COUNT * 2), 'y']]
|
||||
])('preserves line boundaries for input %#', async (content, expected) => {
|
||||
expect(await collect(content as string, new AbortController().signal)).toEqual(expected)
|
||||
})
|
||||
|
||||
it('rejects an already cancelled scan even for empty content', async () => {
|
||||
const controller = new AbortController()
|
||||
controller.abort()
|
||||
await expect(collect('', controller.signal)).rejects.toThrow()
|
||||
})
|
||||
|
||||
it.each(['\n'.repeat(400), `${'x'.repeat(300_000)}\nlast`])(
|
||||
'observes cancellation at an event-loop yield for input %#',
|
||||
async (content) => {
|
||||
const controller = new AbortController()
|
||||
setImmediate(() => controller.abort())
|
||||
await expect(collect(content, controller.signal)).rejects.toThrow()
|
||||
}
|
||||
)
|
||||
|
||||
it('observes cancellation inside a newline-free segment before emitting its line', async () => {
|
||||
const controller = new AbortController()
|
||||
const seen: string[] = []
|
||||
setImmediate(() => controller.abort())
|
||||
const scan = (async () => {
|
||||
for await (const line of remoteSessionContentLines(
|
||||
'x'.repeat(YIELD_CHAR_COUNT * 3),
|
||||
controller.signal
|
||||
)) {
|
||||
seen.push(line)
|
||||
}
|
||||
})()
|
||||
await expect(scan).rejects.toThrow()
|
||||
expect(seen).toEqual([])
|
||||
})
|
||||
})
|
||||
@@ -27,7 +27,19 @@ async function* cancellableContentLines(
|
||||
|
||||
for (let index = 0; index <= content.length; index++) {
|
||||
if (index < content.length && content.charCodeAt(index) !== 10) {
|
||||
continue
|
||||
const newline = content.indexOf('\n', index)
|
||||
const lineBreak = newline === -1 ? content.length : newline
|
||||
// Bound the jump so a newline-free segment still observes cancellation.
|
||||
const windowEnd = yieldStart + REMOTE_CONTENT_YIELD_CHAR_COUNT
|
||||
if (lineBreak > windowEnd) {
|
||||
await yieldUnlessCancelled(signal)
|
||||
linesSinceYield = 0
|
||||
yieldStart = windowEnd
|
||||
// Resume the search at windowEnd itself; the loop increment lands there.
|
||||
index = windowEnd - 1
|
||||
continue
|
||||
}
|
||||
index = lineBreak
|
||||
}
|
||||
const lineEnd = index > lineStart && content.charCodeAt(index - 1) === 13 ? index - 1 : index
|
||||
yield content.slice(lineStart, lineEnd)
|
||||
@@ -37,11 +49,15 @@ async function* cancellableContentLines(
|
||||
linesSinceYield >= REMOTE_CONTENT_YIELD_LINE_COUNT ||
|
||||
index - yieldStart >= REMOTE_CONTENT_YIELD_CHAR_COUNT
|
||||
) {
|
||||
throwIfAiVaultScanCancelled(signal)
|
||||
await yieldToEventLoop()
|
||||
throwIfAiVaultScanCancelled(signal)
|
||||
await yieldUnlessCancelled(signal)
|
||||
linesSinceYield = 0
|
||||
yieldStart = index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function yieldUnlessCancelled(signal: AbortSignal): Promise<void> {
|
||||
throwIfAiVaultScanCancelled(signal)
|
||||
await yieldToEventLoop()
|
||||
throwIfAiVaultScanCancelled(signal)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user