Skip to content

[Bug] debug logger blocks main-process event loop with appendFileSync per event #410

@samzong

Description

@samzong

Problem

createDebugLogger writes every event to disk via appendFileSync — a synchronous call that blocks the Node event loop on every log. The debug logger is called from extremely hot paths: packages/desktop/src/main/ws/gateway-client.ts alone has 30+ call sites covering reconnect, stream parse, message flow, and error branches. Under load (reconnect storm, large stream, burst IPC traffic), every log call stalls the main process just long enough for cumulative latency to become noticeable, and worse, the main process event loop backs up behind disk I/O. On slow or networked filesystems this can become visible as UI hitches.

Location

File: packages/desktop/src/main/debug/logger.ts:72

appendFileSync(currentFilePath(), `${JSON.stringify(event)}\n`, 'utf8');

Each call also re-opens and re-closes the file (no fd caching), adding more syscall overhead.

Fix Approach

  1. Keep a persistent fs.createWriteStream (or a writable fd) open for the current day's log file. Rotate the stream on date change.
  2. Write asynchronously via stream.write(...). For back-pressure safety, watch the return value and await the drain event if it returns false.
  3. Optionally batch events in-memory with a short flush interval (e.g. 50 ms or 100 events) to further reduce syscall frequency.
  4. Flush and close the stream on app.before-quit.

Verification

  1. Run pnpm check — must pass.
  2. Micro-benchmark: log 10,000 events in a tight loop and compare main-process wall-clock time before / after.
  3. Manual: tail the log file during a reconnect to confirm events still appear in real time (no excessive buffering).

Context

  • WG: Observability & DX
  • Priority: Low (performance — quality of life)
  • Estimated effort: 1-2 hours

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/dxObservability & DX WGhelp wantedExtra attention is neededkind/bugCategorizes issue or PR as related to a bug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions