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

   ## What
   
   `dataListener.interestedURL` was a plain slice with no lock; 
`AddInterestedURL` appends from the `DoSubscribe` path while `DataChange` reads 
it (`slices.ContainsFunc`) on the etcd watch goroutine, racing the slice header.
   
   ## Why
   
   ```go
   // registry/etcdv3/listener.go (before)
   type dataListener struct {
       interestedURL []*common.URL   // no lock
       listener      config_center.ConfigurationListener
   }
   func (l *dataListener) AddInterestedURL(url *common.URL) {
       l.interestedURL = append(l.interestedURL, url)   // DoSubscribe path
   }
   func (l *dataListener) DataChange(eventType remoting.Event) bool {
       ...
       if slices.ContainsFunc(l.interestedURL, serviceURL.URLEqual) {  // etcd 
watch goroutine
           l.listener.Process(...)
       }
   }
   ```
   
   Two near-simultaneous `DoSubscribe` calls, or a subscribe concurrent with an 
incoming etcd watch event, race on the slice header → torn reads, missed event 
matching. `go test -race` flags it.
   
   ## Fix
   
   Add a `sync.RWMutex` to `dataListener`. `AddInterestedURL` takes the write 
lock; `DataChange` does the `ContainsFunc` check under `RLock`, releases it, 
then dispatches `Process` outside the lock.
   
   ## Tests
   
   Added `Test_dataListener_ConcurrentAddAndDataChange`: 100 rounds of 
concurrent `AddInterestedURL` vs `DataChange`, passing under `-race`. 
`registry/etcdv3` passes under `-race`.
   
   Fixes #3544


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