fix(mutual): advance the search when refine collapses a pass window

findMutualPassesFallback skips a candidate with `if (refinedLos <= refinedAos)
continue` but left searchStart untouched, so the next loop iteration called
findNextMutualPass with the same start time and received the same pass again.
Today that branch is theoretically unreachable: refineEdge's 70 s window always
spans findNextMutualPass's 60 s sampling step, so the refined AOS/LOS can only
move inward and never cross. But the invariant is fragile - any future change
to the search step or the refine window (or a near-horizon pass whose
crossings land at the window edges) makes the loop spin forever on one pass,
freezing the query coroutine.

Advance searchStart past the collapsed pass before skipping, breaking the
cycle regardless of how the windows shift. Behaviour for the current reachable
paths is unchanged.
This commit is contained in:
mckero committed 2026-08-17 17:56:09 +00:00
1 parent 8f56ea05ec
commit 16c746f552
1 file changed
+9 -1
@@ -400,7 +400,15 @@ class MutualViewModel(
val refinedAos = refineEdge(sat, posA, posB, aos, 1_000L, true)
val refinedLos = refineEdge(sat, posA, posB, los, 1_000L, false)
if (refinedLos <= refinedAos) continue
if (refinedLos <= refinedAos) {
// Refine collapsed the window (e.g. a near-horizon pass whose
// AOS/LOS both sit at the edge of the 70 s refine window).
// Advance the search regardless: skipping without moving
// searchStart would make findNextMutualPass return the same
// pass forever once the refine windows can no longer span it.
searchStart = los + 120_000L
continue
}
val mutualPass = sampleMutualPass(sat, posA, posB, refinedAos, refinedLos,
minElevADeg, minElevBDeg, sampleInterval)