Aias00 opened a new pull request, #3540:
URL: https://github.com/apache/dubbo-go/pull/3540

   ## What
   
   Two bugs in the Zookeeper config_center listener: `RemoveListener` was a 
silent no-op (key mismatch → leak), and the inner listener map had no lock 
(fatal concurrent map read+write).
   
   ## Why
   
   **1. Key mismatch (leak).** `AddListener` stored under the qualified key 
(`buildPath(rootPath, namespace/key)`), but `RemoveListener` passed the **raw** 
caller key, so `CacheListener.RemoveListener` did `keyListeners.Load(rawKey)` → 
never matched → listener never deleted. Every router `RemoveListener` call 
(condition/script/affinity routers) was a no-op; stale listeners kept receiving 
`DataChange` after unsubscribe.
   
   ```go
   // config_center/zookeeper/impl.go (before)
   func (c *zookeeperDynamicConfiguration) AddListener(key string, ...) {
       key = 
strings.Join([]string{c.GetURL().GetParam(constant.ConfigNamespaceKey, ...), 
key}, "/")
       qualifiedKey := buildPath(c.rootPath, key)
       c.cacheListener.AddListener(qualifiedKey, listener)   // stored qualified
   }
   func (c *zookeeperDynamicConfiguration) RemoveListener(key string, ...) {
       c.cacheListener.RemoveListener(key, listener)           // looked up RAW 
-> no-op
   }
   ```
   
   **2. Inner map race (fatal).** `keyListeners` is a `sync.Map` whose value is 
a plain `map[ConfigurationListener]struct{}` with no mutex (unlike 
`metadata/report/zookeeper`'s locked `ListenerSet`). 
`AddListener`/`RemoveListener` (router goroutines) write/delete the inner map; 
`DataChange` (zk event goroutine) ranges it → `fatal error: concurrent map read 
and map write`.
   
   ## Fix
   
   - Add a `qualifyKey(key)` helper used by **both** `AddListener` and 
`RemoveListener` so the keys cannot drift.
   - Replace the inner `map` value with a mutex-guarded `listenerSet` 
(`add`/`remove`/`snapshot`); `DataChange` snapshots under the lock and 
dispatches `Process` outside it.
   
   ## Tests
   
   - `TestZookeeperDynamicConfigurationQualifyKey`: `qualifyKey` produces the 
same key for Add/Remove (with and without an explicit namespace).
   - `TestListenerSetConcurrency`: 100 rounds of concurrent 
`add`/`remove`/`snapshot` under `-race`.
   - Updated existing `CacheListener` tests for the new `listenerSet` value 
type.
   
   `config_center/zookeeper` passes under `-race`.
   
   Fixes #3539


-- 
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]

Reply via email to