github.com/polarismesh/polaris@v1.17.8/cache/service/ratelimit_query.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package service 19 20 import ( 21 "sort" 22 "strings" 23 24 types "github.com/polarismesh/polaris/cache/api" 25 "github.com/polarismesh/polaris/common/model" 26 "github.com/polarismesh/polaris/common/utils" 27 ) 28 29 // forceUpdate 更新配置 30 func (rlc *rateLimitCache) forceUpdate() error { 31 if err := rlc.Update(); err != nil { 32 return err 33 } 34 return nil 35 } 36 37 // QueryRateLimitRules 38 func (rlc *rateLimitCache) QueryRateLimitRules(args types.RateLimitRuleArgs) (uint32, []*model.RateLimit, error) { 39 if err := rlc.forceUpdate(); err != nil { 40 return 0, nil, err 41 } 42 43 hasService := len(args.Service) != 0 44 hasNamespace := len(args.Namespace) != 0 45 46 res := make([]*model.RateLimit, 0, 8) 47 process := func(rule *model.RateLimit) { 48 if hasService && args.Service != rule.Proto.GetService().GetValue() { 49 return 50 } 51 if hasNamespace && args.Namespace != rule.Proto.GetNamespace().GetValue() { 52 return 53 } 54 if args.ID != "" && args.ID != rule.ID { 55 return 56 } 57 if args.Name != "" { 58 name, _ := utils.ParseWildName(args.Name) 59 if !strings.Contains(rule.Name, name) { 60 return 61 } 62 } 63 64 if args.Disable != nil && *args.Disable != rule.Disable { 65 return 66 } 67 res = append(res, rule) 68 } 69 rlc.IteratorRateLimit(process) 70 amount, routings := rlc.sortBeforeTrim(res, args) 71 return amount, routings, nil 72 } 73 74 func (rlc *rateLimitCache) sortBeforeTrim(rules []*model.RateLimit, 75 args types.RateLimitRuleArgs) (uint32, []*model.RateLimit) { 76 amount := uint32(len(rules)) 77 if args.Offset >= amount || args.Limit == 0 { 78 return amount, nil 79 } 80 sort.Slice(rules, func(i, j int) bool { 81 asc := strings.ToLower(args.OrderType) == "asc" || args.OrderType == "" 82 if strings.ToLower(args.OrderField) == "priority" { 83 return orderByRateLimitPriority(rules[i], rules[j], asc) 84 } 85 return orderByRateLimitModifyTime(rules[i], rules[j], asc) 86 }) 87 endIdx := args.Offset + args.Limit 88 if endIdx > amount { 89 endIdx = amount 90 } 91 return amount, rules[args.Offset:endIdx] 92 } 93 94 func orderByRateLimitPriority(a, b *model.RateLimit, asc bool) bool { 95 if a.Priority < b.Priority { 96 return asc 97 } 98 if a.Priority > b.Priority { 99 // false && asc always false 100 return false 101 } 102 return strings.Compare(a.ID, b.ID) < 0 && asc 103 } 104 105 func orderByRateLimitModifyTime(a, b *model.RateLimit, asc bool) bool { 106 if a.ModifyTime.After(b.ModifyTime) { 107 return asc 108 } 109 if a.ModifyTime.Before(b.ModifyTime) { 110 return false 111 } 112 return strings.Compare(a.ID, b.ID) < 0 && asc 113 }