Skip to content

Fix insights rarity-scores 500s and data-completeness timeout logging#375

Merged
SimplicityGuy merged 2 commits into
mainfrom
worktree-fix-insights-computations
May 31, 2026
Merged

Fix insights rarity-scores 500s and data-completeness timeout logging#375
SimplicityGuy merged 2 commits into
mainfrom
worktree-fix-insights-computations

Conversation

@SimplicityGuy

Copy link
Copy Markdown
Owner

Why

The discogsography-insights scheduler logs showed two computations failing on every run:

1. release_rarity → 500 every run. The API logs traced it to:

neo4j.exceptions.TransientError: Neo.TransientError.General.MemoryPoolOutOfMemoryError
... would use more than the limit 16.0 GiB ... dbms.memory.transaction.total.max
  at api/queries/rarity_queries.py (fetch_all_rarity_signals)

fetch_all_rarity_signals fired 8 full-graph Cypher scans concurrently via asyncio.gather, summing their working sets past the Neo4j transaction-memory pool. Two scans also used size([(r)-[]-() | 1]), which materialises a list element per relationship for every Release.

2. data_completeness → intermittent failure logged as error="". An httpx.ReadTimeout (whose str() is empty) at the 600s client timeout; the underlying full-table scan ranges from ~230s to >600s, so it timed out on 3 of 4 observed days — with no diagnosable log line.

What changed

I1 — rarity-scores OOM:

  • Run the 8 queries sequentially instead of asyncio.gather — caps peak transaction memory at one query (it's a daily background job, so wall-clock is fine).
  • Replace size([(r)-[]-() | 1]) with COUNT { } in the two degree queries — counts without materialising a per-relationship list.
  • Endpoint catches neo4j.exceptions.TransientError → returns 503 (retryable) instead of a bare 500.

I2 — data-completeness blind timeout:

  • New _describe_error helper that always includes the exception type (so ReadTimeout no longer logs as error=""); applied to both the data-completeness and rarity error handlers.
  • Raise the data-completeness client timeout 600s → 1200s (the endpoint caches 6h in Redis, so only the cold path is slow). Rarity's client timeout is likewise raised since its scans now run sequentially.

Verification

  • ✅ Full tests/api + tests/insights suites pass
  • ✅ New tests: 503-on-TransientError endpoint behaviour; _describe_error names the type for empty-message exceptions
  • ✅ ruff + mypy + full pre-commit gate on changed files

🤖 Generated with Claude Code

…meouts

Production insights logs showed two recurring scheduler failures:

1. `release_rarity` failed every run with a 500 from
   `GET /api/internal/insights/rarity-scores`. The API logs traced it to a
   Neo4j `TransientError: MemoryPoolOutOfMemoryError` — `fetch_all_rarity_signals`
   fired eight full-graph Cypher scans concurrently via `asyncio.gather`, summing
   their working sets past `dbms.memory.transaction.total.max` (16 GiB). Two of
   the scans also used `size([(r)-[]-() | 1])`, which materialises a list element
   per relationship for every Release.

   Fix: run the eight queries sequentially (caps peak transaction memory at one
   query; fine for a daily background job) and replace the list-comprehension
   degree with `COUNT { }`. The endpoint now also catches `TransientError` and
   returns 503 instead of a bare 500, so the caller logs a meaningful, retryable
   failure.

2. `data_completeness` failed intermittently with `error=""` — an empty,
   undiagnosable log line. The cause was an `httpx.ReadTimeout` (whose `str()`
   is empty) at the 600s client timeout; the underlying full-table scan varies
   from ~230s to >600s.

   Fix: a `_describe_error` helper that always includes the exception type
   (applied to both the data-completeness and rarity handlers), and a larger
   timeout (1200s) giving the cold-cache scan headroom. The rarity client
   timeout is likewise raised, since its scans now run sequentially.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented May 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@SimplicityGuy SimplicityGuy merged commit b673bac into main May 31, 2026
3 checks passed
@SimplicityGuy SimplicityGuy deleted the worktree-fix-insights-computations branch May 31, 2026 18:51
@github-actions

Copy link
Copy Markdown
Contributor

E2E Coverage (webkit)

Totals Coverage
Statements: 46.29% ( 1246 / 2692 )
Lines: 46.29% ( 1246 / 2692 )

StandWithUkraine

@github-actions

Copy link
Copy Markdown
Contributor

E2E Coverage (chromium)

Totals Coverage
Statements: 46.29% ( 1246 / 2692 )
Lines: 46.29% ( 1246 / 2692 )

StandWithUkraine

@github-actions

Copy link
Copy Markdown
Contributor

E2E Coverage (firefox)

Totals Coverage
Statements: 46.29% ( 1246 / 2692 )
Lines: 46.29% ( 1246 / 2692 )

StandWithUkraine

@github-actions

Copy link
Copy Markdown
Contributor

E2E Coverage (webkit - iPhone 15)

Totals Coverage
Statements: 46.29% ( 1246 / 2692 )
Lines: 46.29% ( 1246 / 2692 )

StandWithUkraine

@github-actions

Copy link
Copy Markdown
Contributor

E2E Coverage (webkit - iPad Pro 11)

Totals Coverage
Statements: 46.29% ( 1246 / 2692 )
Lines: 46.29% ( 1246 / 2692 )

StandWithUkraine

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