mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
revert(terminal): stop pacing latency-sensitive foreground redraws
Dense-SGR pacing was also applied to foreground writes inside the post-keystroke window. There it traded an unmeasured benefit for two concrete costs: a macrotask delay before first paint, since the write became an enqueue plus a zero-delay drain, and up to eight viewport snapshot/settle cycles where there had been one, because the forced refresh flag rides every split batch. The 128 KiB parser burst this pacing exists to bound lives on the background and drain paths, which keep all of it. Restore the synchronous write on the latency-sensitive path and pin it with a test.
This commit is contained in:
@@ -613,16 +613,10 @@ describe('pane terminal output scheduler', () => {
|
||||
expect(terminal.write.mock.calls.map(([data]) => data).join('')).toBe(`${dense}${tail}`)
|
||||
})
|
||||
|
||||
it('paces a latency-sensitive dense foreground redraw instead of writing it whole', async () => {
|
||||
it('writes a latency-sensitive foreground redraw whole, even when it is dense', async () => {
|
||||
vi.useFakeTimers()
|
||||
const { writeTerminalOutput } = await loadScheduler()
|
||||
const terminal = createForegroundTerminal()
|
||||
const parsed: (() => void)[] = []
|
||||
terminal.write.mockImplementation((_data: string, callback?: () => void) => {
|
||||
if (callback) {
|
||||
parsed.push(callback)
|
||||
}
|
||||
})
|
||||
const dense = Array.from(
|
||||
{ length: 1_300 },
|
||||
(_, index) => `\x1b[${30 + (index % 8)}mX\x1b[0m`
|
||||
@@ -630,30 +624,9 @@ describe('pane terminal output scheduler', () => {
|
||||
|
||||
writeTerminalOutput(terminal, dense, { foreground: true, latencySensitive: true })
|
||||
|
||||
// The redraw is queued rather than submitted whole, then released one
|
||||
// parser batch at a time.
|
||||
expect(terminal.write).not.toHaveBeenCalled()
|
||||
vi.advanceTimersByTime(0)
|
||||
expect(terminal.write).toHaveBeenCalledTimes(1)
|
||||
expect(terminal.write.mock.calls[0]?.[0]).toHaveLength(4 * 1024)
|
||||
|
||||
while (parsed.length > 0) {
|
||||
parsed.shift()?.()
|
||||
vi.advanceTimersByTime(0)
|
||||
}
|
||||
expect(terminal.write.mock.calls.map(([data]) => data).join('')).toBe(dense)
|
||||
expect(terminal.write.mock.calls.length).toBeGreaterThan(1)
|
||||
})
|
||||
|
||||
it('writes a latency-sensitive foreground redraw whole when it is not dense', async () => {
|
||||
vi.useFakeTimers()
|
||||
const { writeTerminalOutput } = await loadScheduler()
|
||||
const terminal = createForegroundTerminal()
|
||||
const plain = 'plain redraw line\r\n'.repeat(1_000)
|
||||
|
||||
writeTerminalOutput(terminal, plain, { foreground: true, latencySensitive: true })
|
||||
|
||||
expect(terminal.write.mock.calls.map(([data]) => data)).toEqual([plain])
|
||||
// Pacing this path would delay first paint by a macrotask and multiply the
|
||||
// per-write viewport settle inside the post-keystroke window.
|
||||
expect(terminal.write.mock.calls.map(([data]) => data)).toEqual([dense])
|
||||
})
|
||||
|
||||
it('holds the parse probe behind terminal output the flush could not submit', async () => {
|
||||
|
||||
@@ -34,7 +34,6 @@ import {
|
||||
import {
|
||||
ALWAYS_REFRESH_FOREGROUND_SYNCHRONOUSLY,
|
||||
BACKGROUND_FLUSH_DELAY_MS,
|
||||
DENSE_SGR_CHUNK_CHARS,
|
||||
FOREGROUND_BACKLOG_WARNING,
|
||||
LARGE_BACKLOG_CHARS,
|
||||
discardTerminalOutput,
|
||||
@@ -43,7 +42,6 @@ import {
|
||||
type TerminalOutputTarget,
|
||||
type WriteTerminalOutputOptions
|
||||
} from './pane-terminal-output-queue-registry'
|
||||
import { isDenseSgr } from '../../../../shared/terminal-sgr-density'
|
||||
|
||||
export function writeTerminalOutputImpl(
|
||||
terminal: TerminalOutputTarget,
|
||||
@@ -188,27 +186,6 @@ export function writeTerminalOutputImpl(
|
||||
scheduleDrain(0)
|
||||
return
|
||||
}
|
||||
if (data.length >= DENSE_SGR_CHUNK_CHARS && isDenseSgr(data)) {
|
||||
const queued = entry ?? createQueueEntry(terminal, options)
|
||||
queued.onBackgroundBacklogDropped = options.onBackgroundBacklogDropped
|
||||
queued.highPriority = true
|
||||
queuedByTerminal.set(terminal, queued)
|
||||
enqueueChunk(queued, data, {
|
||||
foreground: true,
|
||||
forceForegroundRefresh: options.forceForegroundRefresh,
|
||||
followupForegroundRefresh: options.followupForegroundRefresh,
|
||||
shouldRefreshForegroundSynchronously: options.shouldRefreshForegroundSynchronously,
|
||||
stripTransientCursorShows: options.stripTransientCursorShows,
|
||||
beforeWrite: options.beforeWrite,
|
||||
onParsed: options.onParsed,
|
||||
ackCredit: options.ackCredit
|
||||
})
|
||||
if (queueCapExceeded(queued)) {
|
||||
replaceBacklogWithWarning(queued, FOREGROUND_BACKLOG_WARNING)
|
||||
}
|
||||
scheduleDrain(0)
|
||||
return
|
||||
}
|
||||
flushTerminalOutputImpl(terminal)
|
||||
const remaining = queuedByTerminal.get(terminal)
|
||||
if (remaining) {
|
||||
|
||||
Reference in New Issue
Block a user