Skip to content

fix: add sync fallback for async adapter reads (read/list/search)#217

Merged
br-raia merged 1 commit into
mainfrom
fix/async-write-persistence
May 18, 2026
Merged

fix: add sync fallback for async adapter reads (read/list/search)#217
br-raia merged 1 commit into
mainfrom
fix/async-write-persistence

Conversation

@br-raia

@br-raia br-raia commented May 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #216 (async write persistence fix). After deploying the write fix, testing revealed:

  • Writes now persist correctly — the async adapter's RETURNING check + sync fallback works
  • Reads are still broken — the async adapter's read(), list(), and search() methods return empty results for entries that ARE committed in the database
  • Sync adapter reads work fine — the quality and history endpoints (which use the sync adapter) correctly return all entries

This confirms the issue is specifically in the async adapter's RLS GUC context during reads — the amfs.current_account_id session variable is likely empty when the async pool checks out connections for read operations, causing RLS policies to hide all entries.

Changes

  1. server.py — read/list/search sync fallbacks: Each endpoint now tries the async adapter first, and if it returns empty/None, transparently falls back to the sync adapter. A warning is logged when the sync adapter finds data the async adapter missed, confirming the RLS context mismatch.

  2. async_adapter.py — GUC diagnostic logging: The _AsyncTenantRLSConnection.__aenter__ now logs a warning when the tenant account_id contextvar is empty at pool checkout, which directly causes the RLS read failure.

Evidence from production testing

Write: version=1 → HTTP 200 ✓
Read: {"status":"not_found"} ✗ (async adapter)
Quality: returns entry correctly ✓ (sync adapter)
History: returns all 4 versions ✓ (sync adapter)
Stats: unchanged at 1038 ✓ (sync adapter)

@br-raia br-raia self-assigned this May 18, 2026
@br-raia br-raia added the bug Something isn't working label May 18, 2026
Writes were persisting correctly (async RETURNING check + sync fallback),
but all read-path endpoints (read, list, search) still routed through
the async adapter whose RLS GUC context is broken — entries committed
by the sync fallback are invisible to async reads.

- read_entry: try async, fall back to sync if entry not found
- list_entries: try async, fall back to sync if result is empty
- search_entries: try async, fall back to sync if no results
- async_adapter: log warning when tenant account_id contextvar is empty
  at pool checkout (helps diagnose the RLS context propagation issue)

Each fallback logs a warning when the sync adapter finds data the async
adapter missed, confirming the RLS context mismatch for investigation.
@br-raia br-raia force-pushed the fix/async-write-persistence branch from 5f0dc6f to a73146f Compare May 18, 2026 03:49
@br-raia br-raia merged commit 39d04d8 into main May 18, 2026
3 checks passed
@br-raia br-raia deleted the fix/async-write-persistence branch May 18, 2026 03:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant