feat(master): serve the experiment list as recently-active plus search - #211
Merged
Merged
Conversation
beinan
force-pushed
the
feat/stats-ui-active-search
branch
4 times, most recently
from
July 27, 2026 17:58
ec3b148 to
8b9eada
Compare
Stacked on lance-format#210. Retirement (lance-format#210) removes cold experiments from the stats table, which is what keeps a scan round proportional to active work. On its own it also removes them from `GET /experiments`, which is only acceptable once they remain findable another way. This closes that. default list the stats table, i.e. experiments written recently enough not to have been retired. A flat list of every experiment ever created is neither renderable nor interesting at tens of thousands. search the stats table, plus the registry for names it no longer holds. Cold matches are observed on demand. detail on a stats miss, resolve through the registry and observe on demand rather than returning 404. So retirement removes an experiment from the *default* view and never makes it unfindable. `observe_cold` deliberately does not write a stats row. Reading about a retired experiment must not make it hot again, or browsing the UI would silently undo retirement and the table would creep back toward holding everything -- the state retirement exists to prevent. It also takes no `MasterState`, so it structurally cannot write one; a refactor that hands it one has to justify itself. Search bounds its on-demand observations by the page size. A query matching thousands of cold experiments must not open thousands of datasets to render one page. Known gap: the two handlers changed here live in `routes.rs`, whose tests all require etcd and are `#[ignore]`d, so CI does not cover them. `observe_cold` is tested in `scanner.rs`, which CI does run. Worth fixing, but as its own change rather than a fourth concern in this one. Co-Authored-By: Claude <noreply@anthropic.com>
beinan
force-pushed
the
feat/stats-ui-active-search
branch
from
July 27, 2026 17:58
8b9eada to
2a61c66
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this exists
#210 removes cold experiments from the stats table — that's what keeps a scan round proportional to active work. But on its own it also removes them from
GET /experiments, which is only acceptable once they stay findable another way. This PR is what makes retirement safe to turn on.Retirement therefore removes an experiment from the default view and never makes it unfindable.
The default is also the right one at scale on its own merits: a flat list of every experiment ever created is neither renderable nor interesting once there are tens of thousands.
Two deliberate decisions
1.
observe_colddoes not write a stats row. Reading about a retired experiment must not make it hot again — otherwise browsing the UI would silently undo retirement, and the table would creep back toward holding everything, which is exactly the state retirement exists to prevent.It also takes no
MasterState, so it structurally cannot write one. A refactor that hands it one has to justify itself. There's a test asserting the no-rehydration property.2. Search bounds its on-demand observations by page size. A query matching thousands of cold experiments must not open thousands of datasets to render one page.
Known gap — stating it rather than hiding it
The two handlers changed here live in
routes.rs, whose tests all require etcd and are#[ignore]d, so CI does not cover them.observe_coldis tested inscanner.rs, which CI does run.So the registry-fallback logic in the handlers is verified locally but not by CI. That's a pre-existing gap in the test structure, worth fixing as its own change rather than as a fourth concern here — and it's the kind of blind spot that only became visible after #202 made CI actually run integration tests.
Testing
Full workspace: 178 core + 30 master + 51 server + 5 concurrency + 1 merge-cleanup, all pass. clippy
-D warningsand fmt clean.The complete picture
This finishes the line of work from the original report (
/experimentsat 30–43s):🤖 Generated with Claude Code