mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
d9e3e206cc
Fixes https://github.com/coder/internal/issues/1474. PR #24549 introduced a `quartz.NewMock` clock + `Trap().NewTimer("drain")` to remove the wall-clock race. However, the trap consumed only **one** `NewTimer("drain")` call via `MustWait/MustRelease`. The merge loop has two code paths that create drain timers with the same tag: - Relay result handler (`drainAndClose` path in `relayReadyCh` case): when an async dial completes after `drainAndClose` was set. - Status notification handler (`relayParts != nil` branch in `statusNotifications` case): when `status!=running` arrives while an active relay exists. Depending on goroutine scheduling, one or both paths fire. When two calls hit the trap, the second blocks the merge loop in `matchCallLocked` (quartz waits for all traps to release). Since the test already moved past `MustWait`, nobody reads the second call from the trap channel, deadlocking the test. - Replace the single `MustWait/MustRelease/Advance` with a goroutine that loops over `trapDrain.Wait`, releasing and advancing for every drain timer. - No production code changes. > 🤖