Aias00 opened a new pull request, #3543:
URL: https://github.com/apache/dubbo-go/pull/3543
## What
`apolloListener.listeners` was a plain `map` with no mutex; `OnNewestChange`
ranges it on agollo's long-poll goroutine while `AddListener`/`RemoveListener`
mutate it on router goroutines — a fatal concurrent map read+write. Same class
as the zk config_center `CacheListener` fix (#3539/#3540).
## Why
```go
// config_center/apollo/listener.go (before)
type apolloListener struct {
listeners map[config_center.ConfigurationListener]struct{} // no lock
}
func (a *apolloListener) OnNewestChange(...) {
for listener := range a.listeners { listener.Process(...) } // agollo
goroutine
}
func (a *apolloListener) AddListener(l ...) { a.listeners[l] = struct{}{} }
// router goroutine
func (a *apolloListener) RemoveListener(l ...) { delete(a.listeners, l) }
// router goroutine
func (a *apolloListener) IsEmpty() bool { return len(a.listeners) ==
0 } // router goroutine
```
A config push from Apollo arriving while a router subscribes/unsubscribes
(or `IsEmpty` runs inside `RemoveListener`'s `RemoveChangeListener` decision) →
`fatal error: concurrent map read and map write`.
## Fix
Add a `sync.RWMutex` to `apolloListener`. `AddListener`/`RemoveListener`
take the write lock; `IsEmpty` takes the read lock; `OnNewestChange` snapshots
the set under the read lock and dispatches `Process` outside it (so a slow
consumer cannot block agollo's long-poll goroutine).
## Tests
Added `TestApolloListenerConcurrency`: 100 rounds of concurrent
`OnNewestChange` vs `Add`/`Remove`, passing under `-race`.
`config_center/apollo` passes under `-race`.
Fixes #3542
--
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]