knyk-dev opened a new issue, #1080:
URL: https://github.com/apache/incubator-seata-go/issues/1080

   ### ✅ 验证清单
   
   - [x] 🔍 我已经搜索过 [现有 
Issues](https://github.com/apache/incubator-seata-go/issues),确信这不是重复问题
   - [x] 🛠️ 我愿意自己处理这个议题
   
   ### 🚀 Go 版本
   
   1.20.14
   
   ### 📦 Seata-go 版本
   
   master
   
   ### 💾 操作系统
   
   🐧 Linux
   
   ### 📝 Bug 描述
   
   `pkg/remoting/loadbalance/consistent_hash_loadbalance.go` has clear 
concurrency bugs in the consistent-hash implementation.
   
   `pick()` reads `sortedHashNodes` without synchronization, while 
`refreshHashCircle()` updates both `sortedHashNodes` and `hashCircle` inside a 
goroutine and only holds `RLock` (read lock) during writes.
   
   This creates data races and can lead to incorrect routing decisions during 
hash-ring rebuilds (session close/reconnect).
   
   Problematic spots include:  
   - `pick()` unsynchronized read of `sortedHashNodes` (around line 61+)  
   - `refreshHashCircle()` writes `sortedHashNodes` / `hashCircle` while 
holding `RLock` (around line 88+)
   
   
   ### 🔄 重现步骤
   
   1. Prepare multiple sessions and trigger consistent-hash picks concurrently. 
 
   2. Concurrently close/reconnect sessions to trigger `refreshHashCircle()` 
via `go c.refreshHashCircle(sessions)`.  
   3. Run race detector against loadbalance package.  
   4. Observe race warnings and occasional inconsistent route behavior.
   
   Example command:
   ```bash
   go test -race ./pkg/remoting/loadbalance -count=100
   ```
   
    `go test -race` log (excerpt):
   ```text
   ==================
   WARNING: DATA RACE
   Read at 0x00c0003f41a8 by goroutine 173:
     seata.apache.org/seata-go/v2/pkg/remoting/loadbalance.(*Consistent).pick()
         pkg/remoting/loadbalance/consistent_hash_loadbalance.go:63 +0x10f
     
seata.apache.org/seata-go/v2/pkg/remoting/loadbalance.ConsistentHashLoadBalance()
         pkg/remoting/loadbalance/consistent_hash_loadbalance.go:163 +0x7c
   
   Previous write at 0x00c0003f41a8 by goroutine 191:
     
seata.apache.org/seata-go/v2/pkg/remoting/loadbalance.(*Consistent).refreshHashCircle()
         pkg/remoting/loadbalance/consistent_hash_loadbalance.go:113 +0x4c4
     
seata.apache.org/seata-go/v2/pkg/remoting/loadbalance.(*Consistent).pick.gowrap1()
         pkg/remoting/loadbalance/consistent_hash_loadbalance.go:80 +0x44
   
   ==================
   WARNING: DATA RACE
   Write at 0x00c0003f4190 by goroutine 191:
     
seata.apache.org/seata-go/v2/pkg/remoting/loadbalance.(*Consistent).refreshHashCircle()
         pkg/remoting/loadbalance/consistent_hash_loadbalance.go:114 +0x51a
   
   Previous read at 0x00c0003f4190 by goroutine 173:
     seata.apache.org/seata-go/v2/pkg/remoting/loadbalance.(*Consistent).pick()
         pkg/remoting/loadbalance/consistent_hash_loadbalance.go:72 +0x1f6
   
   Found 2 data race(s)
   FAIL
   FAIL    seata.apache.org/seata-go/v2/pkg/remoting/loadbalance  3.214s
   ```
   
   
   ### ✅ 预期行为
   
   Consistent-hash ring reads/writes should be properly synchronized.  
   No race detector warnings under concurrent pick + ring refresh.  
   Routing should remain stable during reconnect/rebuild.
   
   ### ❌ 实际行为
   
   Concurrent access races on `sortedHashNodes` and `hashCircle`.  
   Ring rebuild may interleave with reads and produce inconsistent routing / 
fallback behavior.
   
   ### 💡 可能的解决方案
   
   Use proper write locking in `refreshHashCircle()` (`Lock`/`Unlock`), and 
protect all shared reads in `pick()`/`firstKey()` consistently.
   
   A safer pattern is to fully rebuild ring in local variables, then atomically 
swap shared fields under one write lock.
   
   Also add a regression/concurrency test that runs with `-race` and validates 
no race in concurrent pick + refresh scenarios.
   


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