From 6d0a697eca6684e2194834c38ad0d5dd179a46ad Mon Sep 17 00:00:00 2001 From: ShuNing Date: Wed, 27 Dec 2023 16:54:27 +0800 Subject: [PATCH] This is an automated cherry-pick of #7623 close tikv/pd#7206 Signed-off-by: ti-chi-bot --- go.mod | 1 + go.sum | 2 + pkg/mcs/resource_manager/server/manager.go | 8 ++++ .../resource_manager/server/resource_group.go | 47 ++++++++++++++++--- .../server/resource_group_test.go | 42 +++++++++++++++++ .../resource_manager/server/token_bukets.go | 26 ++++++++-- tests/integrations/client/go.sum | 2 + tests/integrations/mcs/go.sum | 2 + tests/integrations/tso/go.sum | 2 + 9 files changed, 122 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 6c67a2e88a5..6b9ba5e1e77 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/kms v1.20.8 github.com/aws/aws-sdk-go-v2/service/sts v1.18.7 github.com/axw/gocov v1.0.0 + github.com/brianvoe/gofakeit/v6 v6.26.3 github.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e github.com/coreos/go-semver v0.3.0 diff --git a/go.sum b/go.sum index 22917e9da5a..6e3a5a47271 100644 --- a/go.sum +++ b/go.sum @@ -71,6 +71,8 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/breeswish/gin-jwt/v2 v2.6.4-jwt-patch h1:KLE/YeX+9FNaGVW5MtImRVPhjDpfpgJhvkuYWBmOYbo= github.com/breeswish/gin-jwt/v2 v2.6.4-jwt-patch/go.mod h1:KjBLriHXe7L6fGceqWzTod8HUB/TP1WWDtfuSYtYXaI= +github.com/brianvoe/gofakeit/v6 v6.26.3 h1:3ljYrjPwsUNAUFdUIr2jVg5EhKdcke/ZLop7uVg1Er8= +github.com/brianvoe/gofakeit/v6 v6.26.3/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= diff --git a/pkg/mcs/resource_manager/server/manager.go b/pkg/mcs/resource_manager/server/manager.go index d50b9c32b8b..5d672462194 100644 --- a/pkg/mcs/resource_manager/server/manager.go +++ b/pkg/mcs/resource_manager/server/manager.go @@ -278,7 +278,11 @@ func (m *Manager) GetResourceGroup(name string) *ResourceGroup { m.RLock() defer m.RUnlock() if group, ok := m.groups[name]; ok { +<<<<<<< HEAD:pkg/mcs/resource_manager/server/manager.go return group.Copy() +======= + return group.Clone(withStats) +>>>>>>> ed9685a79 (resource_mananger: deep clone resource group (#7623)):pkg/mcs/resourcemanager/server/manager.go } return nil } @@ -298,7 +302,11 @@ func (m *Manager) GetResourceGroupList() []*ResourceGroup { m.RLock() res := make([]*ResourceGroup, 0, len(m.groups)) for _, group := range m.groups { +<<<<<<< HEAD:pkg/mcs/resource_manager/server/manager.go res = append(res, group.Copy()) +======= + res = append(res, group.Clone(withStats)) +>>>>>>> ed9685a79 (resource_mananger: deep clone resource group (#7623)):pkg/mcs/resourcemanager/server/manager.go } m.RUnlock() sort.Slice(res, func(i, j int) bool { diff --git a/pkg/mcs/resource_manager/server/resource_group.go b/pkg/mcs/resource_manager/server/resource_group.go index 9fbc4a09123..e950c106e15 100644 --- a/pkg/mcs/resource_manager/server/resource_group.go +++ b/pkg/mcs/resource_manager/server/resource_group.go @@ -20,6 +20,7 @@ import ( "sync" "time" + "github.com/gogo/protobuf/proto" "github.com/pingcap/errors" rmpb "github.com/pingcap/kvproto/pkg/resource_manager" "github.com/pingcap/log" @@ -42,6 +43,20 @@ type RequestUnitSettings struct { RU *GroupTokenBucket `json:"r_u,omitempty"` } +// Clone returns a deep copy of the RequestUnitSettings. +func (rus *RequestUnitSettings) Clone() *RequestUnitSettings { + if rus == nil { + return nil + } + var ru *GroupTokenBucket + if rus.RU != nil { + ru = rus.RU.Clone() + } + return &RequestUnitSettings{ + RU: ru, + } +} + // NewRequestUnitSettings creates a new RequestUnitSettings with the given token bucket. func NewRequestUnitSettings(tokenBucket *rmpb.TokenBucket) *RequestUnitSettings { return &RequestUnitSettings{ @@ -58,21 +73,39 @@ func (rg *ResourceGroup) String() string { return string(res) } +<<<<<<< HEAD:pkg/mcs/resource_manager/server/resource_group.go // Copy copies the resource group. func (rg *ResourceGroup) Copy() *ResourceGroup { // TODO: use a better way to copy +======= +// Clone copies the resource group. +func (rg *ResourceGroup) Clone(withStats bool) *ResourceGroup { +>>>>>>> ed9685a79 (resource_mananger: deep clone resource group (#7623)):pkg/mcs/resourcemanager/server/resource_group.go rg.RLock() defer rg.RUnlock() - res, err := json.Marshal(rg) - if err != nil { - panic(err) + newRG := &ResourceGroup{ + Name: rg.Name, + Mode: rg.Mode, + Priority: rg.Priority, + RUSettings: rg.RUSettings.Clone(), } - var newRG ResourceGroup - err = json.Unmarshal(res, &newRG) - if err != nil { - panic(err) + if rg.Runaway != nil { + newRG.Runaway = proto.Clone(rg.Runaway).(*rmpb.RunawaySettings) } +<<<<<<< HEAD:pkg/mcs/resource_manager/server/resource_group.go return &newRG +======= + + if rg.Background != nil { + newRG.Background = proto.Clone(rg.Background).(*rmpb.BackgroundSettings) + } + + if withStats && rg.RUConsumption != nil { + newRG.RUConsumption = proto.Clone(rg.RUConsumption).(*rmpb.Consumption) + } + + return newRG +>>>>>>> ed9685a79 (resource_mananger: deep clone resource group (#7623)):pkg/mcs/resourcemanager/server/resource_group.go } func (rg *ResourceGroup) getRUToken() float64 { diff --git a/pkg/mcs/resource_manager/server/resource_group_test.go b/pkg/mcs/resource_manager/server/resource_group_test.go index c0be8851b97..84841eecb05 100644 --- a/pkg/mcs/resource_manager/server/resource_group_test.go +++ b/pkg/mcs/resource_manager/server/resource_group_test.go @@ -2,8 +2,10 @@ package server import ( "encoding/json" + "reflect" "testing" + "github.com/brianvoe/gofakeit/v6" rmpb "github.com/pingcap/kvproto/pkg/resource_manager" "github.com/stretchr/testify/require" ) @@ -29,8 +31,48 @@ func TestPatchResourceGroup(t *testing.T) { re.NoError(err) err = rg.PatchSettings(patch) re.NoError(err) +<<<<<<< HEAD:pkg/mcs/resource_manager/server/resource_group_test.go res, err := json.Marshal(rg.Copy()) +======= + res, err := json.Marshal(rg.Clone(false)) +>>>>>>> ed9685a79 (resource_mananger: deep clone resource group (#7623)):pkg/mcs/resourcemanager/server/resource_group_test.go re.NoError(err) re.Equal(ca.expectJSONString, string(res)) } } + +func resetSizeCache(obj interface{}) { + resetSizeCacheRecursive(reflect.ValueOf(obj)) +} + +func resetSizeCacheRecursive(value reflect.Value) { + if value.Kind() == reflect.Ptr { + value = value.Elem() + } + + if value.Kind() != reflect.Struct { + return + } + + for i := 0; i < value.NumField(); i++ { + fieldValue := value.Field(i) + fieldType := value.Type().Field(i) + + if fieldType.Name == "XXX_sizecache" && fieldType.Type.Kind() == reflect.Int32 { + fieldValue.SetInt(0) + } else { + resetSizeCacheRecursive(fieldValue) + } + } +} + +func TestClone(t *testing.T) { + for i := 0; i <= 10; i++ { + var rg ResourceGroup + gofakeit.Struct(&rg) + // hack to reset XXX_sizecache, gofakeit will random set this field but proto clone will not copy this field. + resetSizeCache(&rg) + rgClone := rg.Clone(true) + require.EqualValues(t, &rg, rgClone) + } +} diff --git a/pkg/mcs/resource_manager/server/token_bukets.go b/pkg/mcs/resource_manager/server/token_bukets.go index 47608203847..88e1be02942 100644 --- a/pkg/mcs/resource_manager/server/token_bukets.go +++ b/pkg/mcs/resource_manager/server/token_bukets.go @@ -49,6 +49,22 @@ type GroupTokenBucket struct { GroupTokenBucketState `json:"state,omitempty"` } +// Clone returns the deep copy of GroupTokenBucket +func (gtb *GroupTokenBucket) Clone() *GroupTokenBucket { + if gtb == nil { + return nil + } + var settings *rmpb.TokenLimitSettings + if gtb.Settings != nil { + settings = proto.Clone(gtb.Settings).(*rmpb.TokenLimitSettings) + } + stateClone := *gtb.GroupTokenBucketState.Clone() + return &GroupTokenBucket{ + Settings: settings, + GroupTokenBucketState: stateClone, + } +} + func (gtb *GroupTokenBucket) setState(state *GroupTokenBucketState) { gtb.Tokens = state.Tokens gtb.LastUpdate = state.LastUpdate @@ -85,10 +101,14 @@ type GroupTokenBucketState struct { // Clone returns the copy of GroupTokenBucketState func (gts *GroupTokenBucketState) Clone() *GroupTokenBucketState { - tokenSlots := make(map[uint64]*TokenSlot) - for id, tokens := range gts.tokenSlots { - tokenSlots[id] = tokens + var tokenSlots map[uint64]*TokenSlot + if gts.tokenSlots != nil { + tokenSlots = make(map[uint64]*TokenSlot) + for id, tokens := range gts.tokenSlots { + tokenSlots[id] = tokens + } } + var lastUpdate *time.Time if gts.LastUpdate != nil { newLastUpdate := *gts.LastUpdate diff --git a/tests/integrations/client/go.sum b/tests/integrations/client/go.sum index df83e220389..29736dd4ff0 100644 --- a/tests/integrations/client/go.sum +++ b/tests/integrations/client/go.sum @@ -67,6 +67,8 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/breeswish/gin-jwt/v2 v2.6.4-jwt-patch h1:KLE/YeX+9FNaGVW5MtImRVPhjDpfpgJhvkuYWBmOYbo= github.com/breeswish/gin-jwt/v2 v2.6.4-jwt-patch/go.mod h1:KjBLriHXe7L6fGceqWzTod8HUB/TP1WWDtfuSYtYXaI= +github.com/brianvoe/gofakeit/v6 v6.26.3 h1:3ljYrjPwsUNAUFdUIr2jVg5EhKdcke/ZLop7uVg1Er8= +github.com/brianvoe/gofakeit/v6 v6.26.3/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= diff --git a/tests/integrations/mcs/go.sum b/tests/integrations/mcs/go.sum index 057de20b2c7..8e31048bbbb 100644 --- a/tests/integrations/mcs/go.sum +++ b/tests/integrations/mcs/go.sum @@ -67,6 +67,8 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/breeswish/gin-jwt/v2 v2.6.4-jwt-patch h1:KLE/YeX+9FNaGVW5MtImRVPhjDpfpgJhvkuYWBmOYbo= github.com/breeswish/gin-jwt/v2 v2.6.4-jwt-patch/go.mod h1:KjBLriHXe7L6fGceqWzTod8HUB/TP1WWDtfuSYtYXaI= +github.com/brianvoe/gofakeit/v6 v6.26.3 h1:3ljYrjPwsUNAUFdUIr2jVg5EhKdcke/ZLop7uVg1Er8= +github.com/brianvoe/gofakeit/v6 v6.26.3/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= diff --git a/tests/integrations/tso/go.sum b/tests/integrations/tso/go.sum index e46ec710f45..1fa9808741a 100644 --- a/tests/integrations/tso/go.sum +++ b/tests/integrations/tso/go.sum @@ -67,6 +67,8 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/breeswish/gin-jwt/v2 v2.6.4-jwt-patch h1:KLE/YeX+9FNaGVW5MtImRVPhjDpfpgJhvkuYWBmOYbo= github.com/breeswish/gin-jwt/v2 v2.6.4-jwt-patch/go.mod h1:KjBLriHXe7L6fGceqWzTod8HUB/TP1WWDtfuSYtYXaI= +github.com/brianvoe/gofakeit/v6 v6.26.3 h1:3ljYrjPwsUNAUFdUIr2jVg5EhKdcke/ZLop7uVg1Er8= +github.com/brianvoe/gofakeit/v6 v6.26.3/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=