diff --git a/benchmarks/aft-search/slice-descriptors/land-flake-batch-11.json b/benchmarks/aft-search/slice-descriptors/land-flake-batch-11.json new file mode 100644 index 000000000..a39f7240c --- /dev/null +++ b/benchmarks/aft-search/slice-descriptors/land-flake-batch-11.json @@ -0,0 +1,12 @@ +{ + "slice_class": "non_ranking", + "targeted_mechanism": "none", + "kind": "harness", + "fixtures": [ + "harness-goldens" + ], + "slices": [ + "flake-batch-11" + ], + "note": "Test-only: the watcher-drain rewind test waits by time and yields between slices instead of a 32-slice spin. No changed path matches RANKING_FENCE_PREFIXES." +} diff --git a/crates/aft/src/runtime_drain.rs b/crates/aft/src/runtime_drain.rs index bd1bc80cf..c283e60c2 100644 --- a/crates/aft/src/runtime_drain.rs +++ b/crates/aft/src/runtime_drain.rs @@ -6785,10 +6785,18 @@ mod tests { drain.join().unwrap(); ctx.mark_subc_bound(); - let mut guard = 0; + // The replay must finish: the manual dispatch channel holds no + // platform watcher, so `has_more` can only come from the retained + // Apply continuation. A bound replay advances every slice; the only + // zero-progress park is transient LSP contention from the + // applicability worker spawned by the initial batch. Yield between + // slices so that worker can release the manager, and bound the wait + // by time rather than a fixed slice count, which is brittle under + // CI load. + let deadline = Instant::now() + Duration::from_secs(30); while drain_watcher_events_bounded(&ctx, WATCHER_PATH_DRAIN_BATCH_CAP).has_more { - guard += 1; - assert!(guard < 32, "rebased replay must finish"); + assert!(Instant::now() < deadline, "rebased replay must finish"); + std::thread::yield_now(); } let search = ctx .search_index()