Skip to content

fix(search): keep unfiltered function pages in stable id order - #17

Merged
rdmmf merged 4 commits into
devfrom
worktree-func-sort-id
Jul 27, 2026
Merged

fix(search): keep unfiltered function pages in stable id order#17
rdmmf merged 4 commits into
devfrom
worktree-func-sort-id

Conversation

@rdmmf

@rdmmf rdmmf commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #13.

#13 removed the Kvrocks hang by keeping unfiltered function lists off the Lua path, but it pages straight off SSCAN. That has no stable ordering, so:

  • consecutive pages can overlap or skip rows (the Functions table pages by offset)
  • the same request can return a different page on each call
  • the old Lua path returned ids sorted ascending

The fix is to do what search_file.py and search_feature.py already do on their unfiltered paths: load the set, sort in Python, slice. The hang in #12 came from doing this inside Lua, under the Kvrocks global EVAL lock — #13 already removed that. From Python it's the house pattern, and search_file.py:386 carries a ponytail: comment naming the same ceiling.

Net effect on dev: 17 insertions, 20 deletions — _sscan_page and its truncation bookkeeping go away.

The sort_by != "id" branch with a present zset index is unchanged, and filtered searches still go through Lua.

Ceiling

all_functions is the largest of the three sets, so if any unfiltered path needs a maintained id index first, it's this one. Noted in the docstring rather than pre-built.

Testing

  • helper checked directly: pages are id-sorted, disjoint across offsets, and identical across repeated calls
  • uv run python -m compileall bsimvis/app/routes/search_function.py

🤖 Generated with Claude Code

SegmondFault and others added 4 commits July 11, 2026 12:07
The unfiltered function-list path added in #13 paged straight off SSCAN,
which has no stable ordering. Consecutive pages could overlap or skip
rows, and the same request could return a different page each time —
the old Lua path sorted by id ascending.

There is no id-ordered index to range over (save_function only does
SADD on {col}:all_functions), so bound the scan instead: collect up to
SORT_SCAN_CAP members, sort by id, slice the page, and report anything
beyond the cap via the existing pool_truncated flag. The scan stays
incremental, so it never holds Kvrocks the way the SMEMBERS-in-Lua path
did.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The unfiltered function-list path added in #13 paged straight off SSCAN,
which has no stable ordering. Consecutive pages could overlap or skip
rows, and the same request could return a different page each time — the
old Lua path sorted by id ascending.

Use the same shape as the unfiltered paths in search_file and
search_feature: load the set, sort in Python, slice. The hang in #12 came
from doing this inside Lua under the Kvrocks global EVAL lock, which #13
already removed; from Python the sibling routes have done it this way all
along.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@rdmmf
rdmmf marked this pull request as ready for review July 27, 2026 13:31
@rdmmf
rdmmf merged commit 6d1aab2 into dev Jul 27, 2026
rdmmf added a commit that referenced this pull request Jul 27, 2026
* Avoid Lua full-set reads for unfiltered function lists

* fix(search): keep unfiltered function pages in stable id order

The unfiltered function-list path added in #13 paged straight off SSCAN,
which has no stable ordering. Consecutive pages could overlap or skip
rows, and the same request could return a different page each time —
the old Lua path sorted by id ascending.

There is no id-ordered index to range over (save_function only does
SADD on {col}:all_functions), so bound the scan instead: collect up to
SORT_SCAN_CAP members, sort by id, slice the page, and report anything
beyond the cap via the existing pool_truncated flag. The scan stays
incremental, so it never holds Kvrocks the way the SMEMBERS-in-Lua path
did.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(search): keep unfiltered function pages in stable id order

The unfiltered function-list path added in #13 paged straight off SSCAN,
which has no stable ordering. Consecutive pages could overlap or skip
rows, and the same request could return a different page each time — the
old Lua path sorted by id ascending.

Use the same shape as the unfiltered paths in search_file and
search_feature: load the set, sort in Python, slice. The hang in #12 came
from doing this inside Lua under the Kvrocks global EVAL lock, which #13
already removed; from Python the sibling routes have done it this way all
along.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: SegmondFault <izaakalfredgray@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.

2 participants