8000 fix(api): answer 404 when a clear-scroll frees nothing by amartya1523 · Pull Request #2914 · xerj-org/xerj · GitHub
[go: up one dir, main page]

Skip to content {"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}

fix(api): answer 404 when a clear-scroll frees nothing - #2914

Open
amartya1523 wants to merge 3 commits into
xerj-org:mainfrom
amartya1523:fix/clear-scroll-404
Open

amartya1523 wants to merge 3 commits into
xerj-org:mainfrom
amartya1523:fix/clear-scroll-404

Conversation

@amartya1523
Copy link
Copy Markdown
Contributor

AI-assisted change, run and reviewed by @amartya1523.

What this changes, and why

DELETE /_search/scroll answered 200 when it freed nothing: the same id cleared twice, an expired id, or _all with no open scrolls. ES keeps the body ({"succeeded": true, "num_freed": 0}) but sets the status from it. ClearScrollResponse#status is NOT_FOUND when num_freed == 0. Clients use that status to tell a freed context from a stale id. scroll/11_clear.yml clears an id and then expects catch: missing on clearing it again, and three catch-lenient.txt lines are that step.

Fix: clear_scroll and clear_scroll_path both return clear_scroll_response(num_freed). It keeps the body and answers 404 when nothing was freed. That covers every selector: body id, body id list, ?scroll_id= list, _all and /_search/scroll/{id}. Fetching a cleared scroll already answered 404 (search_context_missing_exception) and is unchanged.

Evidence

Wire, node built from main b78004832 vs this branch:

DELETE /_search/scroll {"scroll_id":"<open id>"}      200 {"succeeded":true,"num_freed":1}   (both)
DELETE /_search/scroll {"scroll_id":"<same id>"}      main 200 -> branch 404 {"succeeded":true,"num_freed":0}
DELETE /_search/scroll/<same id>                      main 200 -> branch 404
DELETE /_search/scroll?scroll_id=_all (none open)     main 200 -> branch 404

New test module clear_scroll_status_tests (es_compat.rs), run against main first:

# main
test es_compat::clear_scroll_status_tests::clearing_nothing_is_a_404 ... FAILED
  left: 200  right: 404
test es_compat::clear_scroll_status_tests::freeing_any_context_is_a_200 ... ok

# this branch
test es_compat::clear_scroll_status_tests::clearing_nothing_is_a_404 ... ok
test es_compat::clear_scroll_status_tests::freeing_any_context_is_a_200 ... ok

Checks

  • cargo fmt --all
  • Scoped build of the touched crate, quick profile (cargo build --profile quick -p xerj-server, per docs/FAST_BUILDS.md). Not --release; see Not run.
  • cargo test --profile quick -p xerj-api --lib: 417 passed, 0 failed (all three sibling fixes applied)
  • ES-YAML suite at 0 failed: 1453 passed · 0 failed · 10 skipped · 1463 total, 65 cases catch-lenient (was 74), no stale-entry notes. Run with es-yaml-runner --dir tests/es-compat-yaml/yaml against a quick node built from main b78004832 plus this PR and its two siblings (fix(api): reject avg/sum/min/max/stats on a non-numeric field like ES #2913 and the scroll-validation PR).
  • YAML case: the three scroll/11_clear.yml cases now enforce it; their catch-lenient lines are deleted.
  • Integration tests run (each alone, quick): every xerj-api/tests file that opens or clears a scroll passes (scroll_, collapse_scroll_, search_scroll_*, rerank/judge stage HTTP, among 31 run).
  • Docs: none describe the old status.

Not run: --release builds and local clippy, for disk reasons (the machine is at 99%). The quick profile from FAST_BUILDS.md was used instead.

Merge note: this and the sibling scroll-validation PR both delete adjacent lines in catch-lenient.txt. Whichever lands second needs a trivial rebase, and I'll do it.

Provenance

  • Written by: AI-assisted, run and reviewed by @amartya1523
  • Verified: the commands and outputs above, on macOS 26 (aarch64), quick profile, based on main b78004832.
  • Assumed: _all with nothing open is also a 404 in ES. That follows from the same num_freed == 0 rule; no YAML case pins it.

Motivation:
Clearing a scroll id that was already cleared or never existed answered
200. ES keeps the body (`{"succeeded": true, "num_freed": 0}`) but sets
the status from it: ClearScrollResponse#status is NOT_FOUND when
`num_freed` is 0. Clients (and `scroll/11_clear.yml`, which clears the
same id twice and expects `catch: missing`) use that status to tell a
freed context from a stale id. Three catch-lenient lines are this case.

Root cause:
`clear_scroll` and `clear_scroll_path` always wrapped the body in a
plain `Json(..)`, i.e. 200.

Fix:
Both handlers return `clear_scroll_response(num_freed)`, which keeps
the body and answers 404 when nothing was freed. That covers the body
id, body id list, `?scroll_id=` list, `_all` and the
`/_search/scroll/{id}` path form. Fetching a cleared scroll already
answered 404 (`search_context_missing_exception`) and is unchanged.

Evidence:
- ES-YAML suite against a node built from this change (with its two
  sibling fixes): `1453 passed · 0 failed · 10 skipped`, no stale
  catch-lenient entries; the three `scroll/11_clear.yml` lines are
  deleted.
A second clear of the same id, the path form on a freed id and `_all`
with nothing open answer 404 with `num_freed: 0`; a clear that frees at
least one context (including a body list mixed with an unknown id, which
wins over the query string) answers 200.

On main the first test fails at the second clear:
  left: 200  right: 404
…ear-scroll-404

# Conflicts:
#	engine/tests/es-compat-yaml/catch-lenient.txt

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0