Aias00 opened a new pull request, #3517: URL: https://github.com/apache/dubbo-go/pull/3517
## What The Zookeeper / etcdv3 / Nacos service-discovery backends read `instanceListenerMap[serviceName]` inside their watcher/subscription callbacks **without holding the lock** that `AddListener` / `registerInstanceListener` / `Destroy` mutate it under. Concurrent subscribe/unsubscribe therefore triggers a fatal `concurrent map read and map write`. ## Why - **zookeeper** `registry/zookeeper/service_discovery.go:279` — `DataChange` iterates `zksd.instanceListenerMap[serviceName].Values()` with no `listenLock`, while `AddListener` (`:238`) and (via `Destroy`) mutate the map under `listenLock`. - **etcdv3** `registry/etcdv3/service_discovery.go:290` — `DataChange` reads `e.instanceListenerMap[...]` with no `initLock`, while `registerServiceInstanceListener`/`registerServiceWatcher` write under `initLock`. Additionally, the decode-error path blanked `ServiceName` to `""` and then looked up `instanceListenerMap[""]` — a silent no-op rather than a real failure. - **nacos** `registry/nacos/service_discovery.go:320` — the `SubscribeCallback` reads `n.instanceListenerMap[serviceName]` with no `listenerLock`, while `registerInstanceListener` and `Destroy` mutate it under `listenerLock`; an in-flight callback delivered after `Destroy` clears the map is a live race. (`gxset.HashSet.Values()` does not panic on a nil receiver, so the issue is the concurrent map access, not a nil deref.) ## Fix Snapshot the listener set under the writer lock, then iterate the snapshot **outside** the lock to dispatch — this both eliminates the race and stops a slow `OnEvent` from blocking every other listener: - **zookeeper** `DataChange`: snapshot under `listenLock` via a new `snapshotListeners` helper; dispatch outside the lock. - **etcdv3** `DataChange`: snapshot under `initLock`; on decode error, log and `return false` instead of blanking `ServiceName`. - **nacos** `SubscribeCallback`: snapshot under `listenerLock` before `OnEvent`. ## Tests Added `TestZookeeperServiceDiscovery_SnapshotListeners` covering: missing key (safe no-op), present key (returns registered listeners), and concurrent snapshot-vs-mutation race-freedom under `-race`. `registry/zookeeper`, `registry/etcdv3`, `registry/nacos` all pass under `-race`. Fixes #3512 -- 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]
