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  }