Aias00 opened a new pull request, #3527:
URL: https://github.com/apache/dubbo-go/pull/3527
## What
Four defects in the failback retry lifecycle. The `cluster/cluster/failback`
package fails `TestFailbackRetryFailed` and `TestFailbackOutOfLimit` under
`-race` on `develop`; this PR makes the package `-race` clean.
## Why
1. **Goroutine leak.** `process` used `for range invoker.ticker.C`.
`Destroy` calls `ticker.Stop()`, but `time.Ticker.Stop()` does not close
`ticker.C`, so the goroutine blocks forever; the loop body's `Peek →
ErrDisposed → return` exit is unreachable (the body only runs on a tick). Every
failback invoker that ever failed a call leaks one goroutine + ticker for the
process lifetime.
2. **`ticker` field race.** Written from the `process` goroutine, read in
`Destroy` with no sync.
3. **`taskList` nil-Dispose.** `taskList` is lazily initialized only on a
failed `Invoke`. `Destroy` on a never-failed invoker nil-derefs
`taskList.Dispose()`.
4. **`retryTimerTask.lastT` race.** `checkRetry` wrote `t.lastT` **after**
`taskList.Put(t)`, while `process` reads `lastT` after `Peek`. The queue's
Put/Peek sync only makes pre-Put writes visible, so the post-Put write raced.
## Fix
- Replaced the `once sync.Once` lazy init with a `mu sync.Mutex` +
`initialized bool` `ensureInit`, so `Destroy` takes the same lock and observes
a consistent state.
- Added a `done chan struct{}`; `process` selects on `ticker.C` **and**
`done` with `defer ticker.Stop()`; `Destroy` closes `done`.
- `Destroy` nil-checks `taskList` before `Dispose`.
- `checkRetry` sets `t.lastT` **before** `taskList.Put(t)`.
## Tests
- `TestFailbackDestroyWithoutRetry`: `Destroy` on a never-failed invoker
does not panic.
- `TestFailbackDestroyStopsProcess`: after a failed `Invoke` + `Destroy`,
the `done` channel is closed (process was signaled to exit).
- `TestFailbackRetryFailed` and `TestFailbackOutOfLimit` (both failing on
`develop` under `-race`) now pass; the whole `cluster/cluster/failback` package
passes `-race -count=2`.
Fixes #3526
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]