Skip to content

Commit

Permalink
perf(circuitbreak): no allocation for MW
Browse files Browse the repository at this point in the history
goos: darwin
goarch: arm64
pkg: github.com/cloudwego/kitex/pkg/circuitbreak
             │  ./old.txt  │             ./new.txt              │
             │   sec/op    │   sec/op     vs base               │
CBSuiteMW-12   95.53n ± 4%   70.98n ± 7%  -25.69% (p=0.002 n=6)

             │ ./old.txt  │             ./new.txt             │
             │    B/op    │   B/op     vs base                │
CBSuiteMW-12   40.00 ± 0%   0.00 ± 0%  -100.00% (p=0.002 n=6)

             │ ./old.txt  │             ./new.txt              │
             │ allocs/op  │ allocs/op   vs base                │
CBSuiteMW-12   2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.002 n=6)
  • Loading branch information
xiaost committed Oct 8, 2024
1 parent 4943f34 commit 4e6969d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 16 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ tool/cmd/kitex/kitex
# remote dump file
*.json
base1.go
dump.txt
base2.go

# tmp files
*.txt
*.bak

# Go workspace file
go.work
go.work.sum
31 changes: 17 additions & 14 deletions pkg/circuitbreak/cbsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"time"

"github.com/bytedance/gopkg/cloud/circuitbreaker"
"github.com/bytedance/gopkg/collection/skipmap"

"github.com/cloudwego/kitex/pkg/discovery"
"github.com/cloudwego/kitex/pkg/endpoint"
Expand All @@ -38,11 +39,11 @@ const (
cbConfig = "cb_config"
)

var defaultCBConfig = CBConfig{Enable: true, ErrRate: 0.5, MinSample: 200}
var defaultCBConfig = &CBConfig{Enable: true, ErrRate: 0.5, MinSample: 200}

// GetDefaultCBConfig return defaultConfig of CircuitBreaker.
func GetDefaultCBConfig() CBConfig {
return defaultCBConfig
return *defaultCBConfig
}

// CBConfig is policy config of CircuitBreaker.
Expand Down Expand Up @@ -96,13 +97,15 @@ type CBSuite struct {
instanceControl *Control

genServiceCBKey GenServiceCBKeyFunc
serviceCBConfig sync.Map // map[serviceCBKey]CBConfig
serviceCBConfig *skipmap.StringMap // map[serviceCBKey]*CBConfig

instanceCBConfig instanceCBConfig

events event.Queue

config CBSuiteConfig

mu sync.Mutex

Check failure on line 108 in pkg/circuitbreak/cbsuite.go

View workflow job for this annotation

GitHub Actions / golangci-lint

field `mu` is unused (unused)
}

// NewCBSuite to build a new CBSuite.
Expand All @@ -112,8 +115,9 @@ func NewCBSuite(genKey GenServiceCBKeyFunc, options ...CBSuiteOption) *CBSuite {
s := &CBSuite{
genServiceCBKey: genKey,
instanceCBConfig: instanceCBConfig{
CBConfig: defaultCBConfig,
CBConfig: GetDefaultCBConfig(),
},
serviceCBConfig: skipmap.NewString(),
config: CBSuiteConfig{
serviceGetErrorTypeFunc: ErrorTypeOnServiceLevel,
instanceGetErrorTypeFunc: ErrorTypeOnInstanceLevel,
Expand Down Expand Up @@ -162,7 +166,7 @@ func (s *CBSuite) ServiceControl() *Control {
// UpdateServiceCBConfig is to update service CircuitBreaker config.
// This func is suggested to be called in remote config module.
func (s *CBSuite) UpdateServiceCBConfig(key string, cfg CBConfig) {
s.serviceCBConfig.Store(key, cfg)
s.serviceCBConfig.Store(key, &cfg)
}

// UpdateInstanceCBConfig is to update instance CircuitBreaker param.
Expand Down Expand Up @@ -221,7 +225,7 @@ func (s *CBSuite) initServiceCB() {
ri := rpcinfo.GetRPCInfo(ctx)
serviceCBKey = s.genServiceCBKey(ri)
cbConfig, _ := s.serviceCBConfig.LoadOrStore(serviceCBKey, defaultCBConfig)
enabled = cbConfig.(CBConfig).Enable
enabled = cbConfig.(*CBConfig).Enable
return
}
s.serviceControl = &Control{
Expand Down Expand Up @@ -297,7 +301,7 @@ func (s *CBSuite) discoveryChangeHandler(e *event.Event) {

func (s *CBSuite) svcTripFunc(key string) circuitbreaker.TripFunc {
pi, _ := s.serviceCBConfig.LoadOrStore(key, defaultCBConfig)
p := pi.(CBConfig)
p := pi.(*CBConfig)
return circuitbreaker.RateTripFunc(p.ErrRate, p.MinSample)
}

Expand Down Expand Up @@ -338,18 +342,17 @@ func cbDebugInfo(panel circuitbreaker.Panel) map[string]interface{} {

func (s *CBSuite) configInfo() map[string]interface{} {
svcCBMap := make(map[string]interface{})
s.serviceCBConfig.Range(func(key, value interface{}) bool {
svcCBMap[key.(string)] = value
s.serviceCBConfig.Range(func(key string, value interface{}) bool {
svcCBMap[key] = *value.(*CBConfig)
return true
})
s.instanceCBConfig.RLock()
instCBConfig := s.instanceCBConfig.CBConfig
s.instanceCBConfig.RUnlock()

cbMap := make(map[string]interface{}, 2)
cbMap[serviceCBKey] = svcCBMap
cbMap[instanceCBKey] = instCBConfig
return cbMap
return map[string]interface{}{
serviceCBKey: svcCBMap,
instanceCBKey: instCBConfig,
}
}

// RPCInfo2Key is to generate circuit breaker key through rpcinfo
Expand Down
13 changes: 12 additions & 1 deletion pkg/circuitbreak/cbsuite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestNewCBSuite(t *testing.T) {
cb := NewCBSuite(RPCInfo2Key)
test.Assert(t, cb.servicePanel == nil)
test.Assert(t, cb.instancePanel == nil)
test.Assert(t, cb.instanceCBConfig.CBConfig == defaultCBConfig)
test.Assert(t, cb.instanceCBConfig.CBConfig == GetDefaultCBConfig())
test.Assert(t, sameFuncPointer(cb.genServiceCBKey, RPCInfo2Key))
test.Assert(t, sameFuncPointer(cb.config.instanceGetErrorTypeFunc, ErrorTypeOnInstanceLevel))
test.Assert(t, sameFuncPointer(cb.config.serviceGetErrorTypeFunc, ErrorTypeOnServiceLevel))
Expand Down Expand Up @@ -661,3 +661,14 @@ func TestCBConfig_Equals(t *testing.T) {
})
}
}

func BenchmarkCBSuiteMW(b *testing.B) {
ctx := prepareCtx()
p := NewCBSuite(func(ri rpcinfo.RPCInfo) string { return "BenchmarkCBSuite" })
smw := p.ServiceCBMW()
noop := func(ctx context.Context, req, resp interface{}) (err error) { return nil }
ep := smw(noop)
for i := 0; i < b.N; i++ {
ep(ctx, b, b)
}
}

0 comments on commit 4e6969d

Please sign in to comment.