Fix the leak count for a Go fan-out query
Your task
An assistant's Go helper queries every replica in its own goroutine and returns the first answer it reads from an unbuffered channel. Nobody reads the channel after that, so every other replica that succeeds blocks forever on its send. That is a goroutine leak, and the team wants to count it for one call.
An assistant wrote count_leaked_goroutines(latency_ms, succeeded, timeout_ms, buffer_capacity, cancel_losers). It is in the editor. It has a bug. Find it and fix it.
Input and output:
latency_ms: how long each replica takes to answer, in milliseconds.succeeded: true for each replica whose query succeeds. If the two lists differ in length, use only as many replicas as the shorter list has.timeout_ms: how long the helper waits for an answer.buffer_capacity: how many sends the channel can hold with nobody reading. 0 or less means none.cancel_losers: true when the helper cancels the other queries as soon as it returns.- Return the number of goroutines blocked forever.
Rules the tests check:
- A replica sends its answer only when its query succeeds. A failed replica never sends.
- The winner is the successful replica with the smallest latency that is at most
timeout_ms. On a tie, the lowest index wins. There may be no winner. - When
cancel_losersis true, return 0: no other replica gets to send. - Otherwise the winner's answer is read, if there is a winner, and nothing is read after that. Every other successful replica still sends, even when it finishes after
timeout_ms, because nothing cancels it. - Each of those sends takes a free buffer slot while one is left. Every send after that blocks forever.
Examples
count_leaked_goroutines(latency_ms: list[int], succeeded: list[bool], timeout_ms: int, buffer_capacity: int, cancel_losers: bool) -> intExample 1
Input
count_leaked_goroutines([10, 20, 30], [True, True, True], 1000, 0, False)Output
2Example 2
Input
count_leaked_goroutines([10, 20, 30], [True, True, True], 1000, 3, False)Output
0Example 3
Input
count_leaked_goroutines([10, 20, 30], [True, True, True], 1000, 0, True)Output
0