Skip to content

perf(#4759): parallelize fresh sidebar boot fetches - #4992

Merged
3 commits merged into
nesquena:masterfrom
rodboev:pr/4759-parallel-sidebar-boot
Jun 26, 2026
Merged

3 commits merged into
nesquena:masterfrom
rodboev:pr/4759-parallel-sidebar-boot

Conversation

@rodboev

@rodboev rodboev commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Thinking Path

  • The current issue is still live, but the earlier backend-side lock stall is not. Current origin/master has already shipped the #4842 cache-rebuild fixes, so the remaining spec has to point at a different seam.
  • The surviving seam is frontend cold-boot sequencing: fresh boot still awaits renderSessionList(), and first-load renderSessionList() still starts /api/projects only after /api/sessions returns.
  • The fix keeps the existing single apply path and only removes that serial tax by starting the independent project request in parallel, backed by an async harness that proves the call order instead of inferring it from source shape.

What Changed

  • static/sessions.js: start the first-load /api/projects request before awaiting /api/sessions, while preserving the current timeout, retry, and fallback behavior.
  • tests/test_issue4759_parallel_sidebar_boot_fetch.py: add async behavioral regression coverage for parallel fetch start order, project-failure fallback, and preserved session request options.
  • tests/test_session_sidebar_resilience.py: update the existing helper-shape assertions so they trace the extracted sidebar payload loader instead of the old inline project fetch block.
  • tests/test_issue4766_sidebar_source_pushdown.py: load the extracted async helper into the existing sidebar-source harness so the refresh-path compatibility checks still exercise the real production call chain.

Why It Matters

Fresh desktop tabs no longer wait for two independent sidebar boot fetches in sequence before the first sidebar payload can complete. The change stays inside the current frontend load contract, which keeps review risk low while still removing a measurable cold-boot tax.

Verification

  • pytest tests/test_issue4759_parallel_sidebar_boot_fetch.py -v --timeout=60
  • pytest tests/test_issue4759_parallel_sidebar_boot_fetch.py tests/test_4167_sidebar_payload_and_scope.py tests/test_1694_root_saved_running_policy.py -v --timeout=60
  • pytest tests/test_issue4759_parallel_sidebar_boot_fetch.py tests/test_session_sidebar_resilience.py tests/test_issue4766_sidebar_source_pushdown.py tests/test_4167_sidebar_payload_and_scope.py tests/test_1694_root_saved_running_policy.py -v --timeout=60

Full-suite CI context, not a required local check unless requested: pytest tests/ -v --timeout=60.

Upstream

Closes #4759.

Builds on the shipped sidebar perf work in #4952 and #4962 by removing the remaining frontend-side serialization on fresh boot.

Model Used

GPT 5.5 via Codex CLI

@greptile-apps

greptile-apps Bot commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR parallelizes the two independent sidebar boot fetches (/api/sessions and /api/projects) by extracting them into a new _loadSidebarSessionListPayload helper that fires the project IIFE immediately, before awaiting sessions, eliminating the serial cold-boot tax.

  • static/sessions.js: projects request is started as an IIFE-backed promise before the session await, then both results are collected; all existing timeout, retry, fallback, and generation-guard behavior is preserved unchanged.
  • tests/test_issue4759_parallel_sidebar_boot_fetch.py: four new Node.js subprocess tests prove parallel call order, project-failure fallback, and session opts fidelity for both cold and warm boot paths.
  • tests/test_issue4766_sidebar_source_pushdown.py / test_session_sidebar_resilience.py: updated to inject the extracted helper into existing harnesses and update shape assertions accordingly, including an _ensure_async guard that prevents the async async function double-keyword issue raised in the previous review.

Confidence Score: 5/5

Safe to merge — the parallelization is correct, all existing guards and fallbacks are preserved, and behavioral tests cover the key call-order invariants.

The extracted helper fires the projects IIFE synchronously before awaiting sessions, achieving true parallelization. Error handling, generation guards, session-request opts, and the warm/cold branch are all faithfully preserved. The _ensure_async guard in the updated test harness correctly addresses the async-async double-keyword concern from the previous review cycle. No regressions were found.

No files require special attention.

Important Files Changed

Filename Overview
static/sessions.js Extracts session+project fetching into _loadSidebarSessionListPayload; projects IIFE starts before sessions await, achieving genuine parallelization while preserving all existing timeout, retry, and fallback behavior.
tests/test_issue4759_parallel_sidebar_boot_fetch.py New async behavioral regression tests exercise parallel fetch start order (cold and warm boot), project-failure fallback, and preserved session request options via a Node.js subprocess harness.
tests/test_issue4766_sidebar_source_pushdown.py Adds _ensure_async guard and injects the new _loadSidebarSessionListPayload helper into the existing harness so the refresh-path compatibility check exercises the real call chain.
tests/test_session_sidebar_resilience.py Updates helper-shape assertions to trace the extracted _loadSidebarSessionListPayload instead of the old inline block; project-isolation invariants are still fully checked.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant R as _runRenderSessionListRefresh
    participant L as _loadSidebarSessionListPayload
    participant AP as /api/projects
    participant AS as /api/sessions

    R->>L: await _loadSidebarSessionListPayload(qs, opts)
    activate L
    L->>AP: api('/api/projects') [IIFE starts, not awaited yet]
    Note over L,AP: projectPromise in flight
    L->>AS: await api('/api/sessions', opts)
    Note over L,AS: sessions and projects now in parallel
    AS-->>L: sessData
    L->>L: await projectPromise
    AP-->>L: projData (or fallback on error)
    L-->>R: "{sessData, projData}"
    deactivate L
    R->>R: generation guard, apply payload
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant R as _runRenderSessionListRefresh
    participant L as _loadSidebarSessionListPayload
    participant AP as /api/projects
    participant AS as /api/sessions

    R->>L: await _loadSidebarSessionListPayload(qs, opts)
    activate L
    L->>AP: api('/api/projects') [IIFE starts, not awaited yet]
    Note over L,AP: projectPromise in flight
    L->>AS: await api('/api/sessions', opts)
    Note over L,AS: sessions and projects now in parallel
    AS-->>L: sessData
    L->>L: await projectPromise
    AP-->>L: projData (or fallback on error)
    L-->>R: "{sessData, projData}"
    deactivate L
    R->>R: generation guard, apply payload
Loading

Reviews (2): Last reviewed commit: "test(#4759): guard async harness extract..." | Re-trigger Greptile

Comment thread tests/test_issue4766_sidebar_source_pushdown.py Outdated
@nesquena-hermes nesquena-hermes added the size:L Large PR (>10 files or >250 LOC) label Jun 26, 2026
@nesquena-hermes nesquena-hermes closed this pull request by merging all changes into nesquena:master in b9cea92 Jun 26, 2026
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Shipped in v0.51.679 (Release YI, just deployed) — thanks @rodboev! Fixes #4759. Fresh sidebar boot now fetches /api/sessions and /api/projects concurrently instead of sequentially. Error handling preserved (a failing project fetch falls back to the cached list without dropping sessions). Gate: Codex SAFE, full suite 10693. Verified on prod.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L Large PR (>10 files or >250 LOC)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(perf): opening a new tab in the desktop app is slow to populate sidebar session list + chat toolbar (cold-boot, slower than a browser tab)

2 participants