Skip to content

fix: close #3247 config/protocol shared-state races#3271

Open
xxs588 wants to merge 5 commits intoapache:developfrom
xxs588:split/3247-config-protocol
Open

fix: close #3247 config/protocol shared-state races#3271
xxs588 wants to merge 5 commits intoapache:developfrom
xxs588:split/3247-config-protocol

Conversation

@xxs588
Copy link

@xxs588 xxs588 commented Mar 19, 2026

Description

Fixes #3247

  • config 中为 rootConfig 增加受控读写路径(GetRootConfig/SetRootConfig),并将 Load 调整为“本地构建并初始化后再发布”
  • protocol/dubbo 中移除包级共享 versionInt map,isSupportResponseAttachment 改为按次调用 version2Int 计算
  • 补充并发回归测试:TestRootConfigConcurrentSetAndGetTestIsSupportResponseAttachmentConcurrent(impl/hessian2)

Verification

  • go test ./config ./protocol/dubbo/impl ./protocol/dubbo/hessian2
  • go test -race ./config -run TestRootConfigConcurrentSetAndGet
  • go test -race ./protocol/dubbo/impl -run TestIsSupportResponseAttachmentConcurrent
  • go test -race ./protocol/dubbo/hessian2 -run TestIsSupportResponseAttachmentConcurrent

Checklist

  • I confirm the target branch is develop
  • Code has passed local testing
  • I have added tests that prove my fix is effective or that my feature works

xxs588 added 2 commits March 19, 2026 15:29
- guard global rootConfig pointer with RWMutex-backed accessors
- make config.Load build a local RootConfig and initialize before publishing
- route config consumers through GetRootConfig instead of direct global reads
- avoid in-place global mutation in SetConsumerConfig
- add concurrent Set/Get regression test for root config

Fixes: apache#3247
- remove package-level versionInt maps in dubbo impl and hessian2 response paths
- compute version int per call to avoid shared mutable/global state
- add concurrent isSupportResponseAttachment tests in both packages

Fixes: apache#3247
@codecov-commenter
Copy link

codecov-commenter commented Mar 19, 2026

Codecov Report

❌ Patch coverage is 34.21053% with 50 lines in your changes missing coverage. Please review.
✅ Project coverage is 48.24%. Comparing base (60d1c2a) to head (3553033).
⚠️ Report is 758 commits behind head on develop.

Files with missing lines Patch % Lines
config/graceful_shutdown.go 0.00% 24 Missing ⚠️
config/config_loader.go 57.14% 6 Missing and 3 partials ⚠️
config/root_config.go 43.75% 9 Missing ⚠️
config/consumer_config.go 0.00% 7 Missing ⚠️
config/provider_config.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3271      +/-   ##
===========================================
+ Coverage    46.76%   48.24%   +1.48%     
===========================================
  Files          295      466     +171     
  Lines        17172    34078   +16906     
===========================================
+ Hits          8031    16442    +8411     
- Misses        8287    16305    +8018     
- Partials       854     1331     +477     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@xxs588 xxs588 force-pushed the split/3247-config-protocol branch from 9a614b1 to 6fb9abe Compare March 19, 2026 07:32
@xxs588 xxs588 marked this pull request as draft March 19, 2026 07:52
@xxs588 xxs588 changed the title fix(race): close #3247 config and protocol shared-state races fix: close #3247 config/protocol shared-state races Mar 19, 2026
@xxs588 xxs588 marked this pull request as ready for review March 19, 2026 15:24
@Alanxtl Alanxtl added ☢️ Bug 3.3.2 version 3.3.2 labels Mar 21, 2026
Comment on lines +42 to +46
func getRootConfigInternal() *RootConfig {
rootConfigMu.RLock()
defer rootConfigMu.RUnlock()
return rootConfig
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个函数有啥用啊 返回的又不是深拷贝

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确实,感谢,我现在去去掉这个加锁的逻辑

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

图片 已经修改了,把加锁逻辑去掉了,换成原子读写rootConfig ,然后修改了相关的单测,将直接读全局变量的地方改成统一走 GetRootConfig()/SetRootConfig()

Copy link
Contributor

@AlexStocks AlexStocks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修复思路清晰,mutex 保护 rootConfig 的方向没问题,并发测试也补得比较完整。有两个小问题,详见行内评论。

@@ -185,7 +185,14 @@ func (cc *ConsumerConfig) Load() {

// SetConsumerConfig sets consumerConfig by @c
func SetConsumerConfig(c ConsumerConfig) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SetConsumerConfig 里的 nil 分支在 rc == nil 时会丢失其他字段。如果 GetRootConfig() 还没被调用过(返回 nil),这里直接 SetRootConfig(RootConfig{Consumer: &c}) 会创建一个只有 Consumer 的 RootConfig,之前通过 Load() 设置的 Protocol、Application 等字段全部丢失。

建议:如果 GetRootConfig() 返回 nil,直接用 NewRootConfigBuilder() 构建一个默认值,再设置 Consumer:

rc := GetRootConfig()
if rc == nil {
    rc = NewRootConfigBuilder().Build()
}
next := *rc
next.Consumer = &c
SetRootConfig(next)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感谢,我将尽快修复

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

图片 已按照建议修复,谢谢

@@ -90,3 +92,24 @@ func TestNewRootConfigBuilder(t *testing.T) {
config := GetRootConfig()
assert.Equal(t, rootConfig, config)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestRootConfigConcurrentSetAndGet 的 200 个并发 goroutine 数量在某些低端 CI 环境(如树莓派或低配虚拟机)上可能会超时或触发 race detector。建议把数量降低到 50,或者加上 go test 的 -p 限制。

另外,这个测试只验证了不 panic 和 GetRootConfig() 非 nil,建议加一个 assert 检查在所有 Set/Get 完成后,GetRootConfig() 返回的是一个有效的 RootConfig(Application.Name 不为空)。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

收到,我现在去修改

Copy link
Author

@xxs588 xxs588 Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

图片 已按照建议修改谢谢大佬 ,增加了结果有效性断言

@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3.3.2 version 3.3.2 ☢️ Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Systematic data races: 20+ extension global maps unprotected, wrong lock in SetProviderService, RouterChain.Route lockless

4 participants