feat: Fix progress bar hanging and improve UI responsiveness during indexing
Adds strategic yield points and direct stdout writes to prevent progress animation from freezing when the main thread is blocked by synchronous operations. Introduces 'finalizing' phase to smooth transition between parsing and resolving steps, ensuring progress reaches 100% completion.
This commit is contained in:
@@ -1,6 +1,16 @@
|
||||
import { parentPort, workerData } from 'worker_threads';
|
||||
import { writeSync } from 'fs';
|
||||
import type { ShimmerWorkerMessage } from './types';
|
||||
|
||||
// Write directly to fd 1 (stdout) instead of writeStdout().
|
||||
// In Node.js worker threads, process.stdout is proxied through the main
|
||||
// thread's event loop — so if the main thread is blocked (e.g. SQLite),
|
||||
// stdout writes from the worker queue up and the animation freezes.
|
||||
// fs.writeSync(1, ...) is a direct kernel syscall that bypasses this.
|
||||
function writeStdout(s: string): void {
|
||||
writeSync(1, s);
|
||||
}
|
||||
|
||||
const SPINNER_GLYPHS = ['·', '✢', '✳', '✶', '✻', '✽'];
|
||||
const ANIM_INTERVAL = 150;
|
||||
const FRAMES_PER_GLYPH = 3;
|
||||
@@ -74,16 +84,16 @@ function render(): void {
|
||||
line = `${DM}│${RST} ${color}${glyph}${RST} ${currentMessage}...`;
|
||||
}
|
||||
|
||||
process.stdout.write(`\r\x1b[K${line}`);
|
||||
writeStdout(`\r\x1b[K${line}`);
|
||||
}
|
||||
|
||||
function finishPhase(): void {
|
||||
if (!currentMessage) return;
|
||||
process.stdout.write(`\r\x1b[K`);
|
||||
writeStdout(`\r\x1b[K`);
|
||||
let detail = '';
|
||||
if (currentPercent >= 0) detail = ' — done';
|
||||
else if (currentCount > 0) detail = ` — ${formatNumber(currentCount)} found`;
|
||||
process.stdout.write(`${DM}│${RST} ${GRN}◆${RST} ${currentMessage}${detail}\n`);
|
||||
writeStdout(`${DM}│${RST} ${GRN}◆${RST} ${currentMessage}${detail}\n`);
|
||||
currentMessage = '';
|
||||
currentPercent = -1;
|
||||
currentCount = 0;
|
||||
|
||||
Reference in New Issue
Block a user