Skip to content

Timeout-then-queue background search#372

Open
level09 wants to merge 3 commits into
mainfrom
feat/background-search
Open

Timeout-then-queue background search#372
level09 wants to merge 3 commits into
mainfrom
feat/background-search

Conversation

@level09

@level09 level09 commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Long searches no longer hold a web worker (and its GIL) hostage. Interactive searches on the bulletin, actor, and incident list endpoints now run under a Postgres statement_timeout (default 30s, SEARCH_TIMEOUT env, 0 disables). When the database cancels one, the same query is re-queued to Celery, which re-runs it with a generous bound (default 10 min, BACKGROUND_SEARCH_TIME_LIMIT), stores up to 10k matching ids in Redis for 24 hours, and notifies the user with a link that replays the stored ids in the normal list view via the existing ids filter.

This is the same sync-with-async-fallback model used by Elasticsearch's async search API (wait_for_completion_timeout) and Superset's SQL Lab (SQLLAB_TIMEOUT + Celery).

  • enferno/utils/background_search.py: timeout helper (SET LOCAL, so the bound dies with the transaction and can't leak through the pool), 57014 detection, Redis result store, and a timeout_fallback decorator that converts a canceled search into a 202 {queued, token} response
  • enferno/tasks/background_search.py: Celery task; id-only select, completion/failure notification (new BACKGROUND_SEARCH_STATUS event, in-app only)
  • The three list endpoints get the decorator plus one apply_search_timeout() call placed after activity logging (the activity commit would otherwise end the transaction and drop the bound)
  • GET /admin/api/background-search/<token>: owner-only stored ids
  • Frontend: 202 shows a snackbar; ?bgs=<token> on the list pages loads stored ids and runs the search

Test plan

  • uv run pytest tests/test_background_search.py (timeout detection via real pg_sleep cancel, result store round-trip, full task run asserting stored ids + notification, endpoint 202 path)
  • tests/test_core_entities.py and tests/test_search_query_combination.py pass unchanged
  • Manual: set SEARCH_TIMEOUT=1, run a heavy search, confirm snackbar, notification, and results link

@level09
level09 requested a review from apodacaduron as a code owner July 19, 2026 18:13
@level09 level09 self-assigned this Jul 19, 2026
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f1778ff-1ab9-4062-b485-9efd1cf2e264

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/background-search

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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