Skip to content

flight-cli: make the calendar GF+Matrix weave concurrent (work-6nrqf)#32

Open
ak2k wants to merge 2 commits into
mainfrom
worktree-calendar-weave
Open

flight-cli: make the calendar GF+Matrix weave concurrent (work-6nrqf)#32
ak2k wants to merge 2 commits into
mainfrom
worktree-calendar-weave

Conversation

@ak2k

@ak2k ak2k commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Summary

Makes the one-way / single-airport calendar weave concurrent (work-6nrqf).

Previously the calendar ran the Google Flights date-grid (~1s, up to ~9s cold) and painted it, then ran the Matrix calendar (~45s) — sequential, so the GF time stacked on top of Matrix.

New _run_calendar_enriched dispatches both under one anyio.run, mirroring the search path's _run_enriched_path: start_soon the Matrix calendar, run the sync GF date-grid in a worker thread concurrently, paint the grid first while Matrix is in flight, then paint the authoritative Matrix calendar. Total wall ≈ max(GF, Matrix) ≈ Matrix alone.

Behavior

  • Per-backend error isolation: a GF throttle (GfThrottledError) or failure still runs + paints Matrix; a Matrix error still shows the GF grid, and exits non-zero only when neither backend produced anything.
  • --fast unchanged — GF date-grid only, no Matrix (the original block, preserved verbatim, just gated on fast).
  • The concurrent path is gated by grid_can_serve, which guarantees a single-airport query, so the Matrix side is a single execute (no fan-out, no merge — the GF grid and Matrix calendar are separate paints).

Tests

3 new orchestration tests in test_calendar_split.py (happy path + GF-throttle isolation + Matrix-error isolation), fakes for both backends, no network.

  • make check green (504 tests).
  • Live-smoked: GF grid paints ~1s then Matrix; total ≈ Matrix alone; both error-isolation paths fired live (Matrix brownout + GF throttle); --fast verified unchanged.

ak2k added 2 commits June 24, 2026 17:51
_run_calendar_enriched dispatches the Google Flights date-grid and the Matrix calendar under one anyio.run (mirroring _run_enriched_path): start_soon Matrix, run the sync GF grid in a worker thread concurrently, paint the grid first while Matrix is in flight, then paint the authoritative Matrix calendar. Total wall ~= max(GF, Matrix) ~= Matrix alone, instead of GF+Matrix sequential.

Per-backend error isolation (GF throttle/failure -> Matrix still paints; Matrix error -> grid still shown). --fast unchanged (GF grid only). The grid_can_serve gate guarantees a single-airport query, so Matrix is one execute (no fan-out). 3 new orchestration tests (happy + GF-throttle + Matrix-error isolation); make check green (504); live-smoked.
…piError Matrix failures + cover gaps

ce-code-review (correctness/adversarial/reliability/maintainability/testing) flagged one real isolation gap: _matrix only caught MatrixApiError, but MatrixClient.execute can raise a raw httpx.HTTPStatusError (re-raised at client.py:130) or an unwrapped transport error. That would escape the task group, cancel the in-flight grid paint, and surface a bare traceback — breaking the documented 'Matrix error -> grid still shown' promise. Broaden _matrix's catch to stash unexpected failures and report them after the weave (grid still paints); extract _report_calendar_matrix_failure to keep the function under the statement cap.

Tests (+4, now 508): non-MatrixApiError still shows grid (the fix's regression test); both-backends-fail -> typer.Exit(1); generic (non-throttle) GF error still paints Matrix; grid-painted-before-Matrix ordering.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant