227 lines
5.5 KiB
Go
227 lines
5.5 KiB
Go
/**
|
|
* Tencent is pleased to support the open source community by making polaris-go available.
|
|
*
|
|
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
|
*
|
|
* Licensed under the BSD 3-Clause License (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://opensource.org/licenses/BSD-3-Clause
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed
|
|
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*/
|
|
|
|
package model
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/hashicorp/go-multierror"
|
|
)
|
|
|
|
// QuotaRequestImpl 配额获取的请求.
|
|
type QuotaRequestImpl struct {
|
|
// 必选,命名空间
|
|
namespace string
|
|
// 必选,服务名
|
|
service string
|
|
// 可选,方法
|
|
method string
|
|
// 可选,业务标签信息
|
|
arguments []Argument
|
|
// 可选,单次查询超时时间,默认直接获取全局的超时配置
|
|
// 用户总最大超时时间为(1+RetryCount) * Timeout
|
|
Timeout *time.Duration
|
|
// 可选,重试次数,默认直接获取全局的超时配置
|
|
RetryCount *int
|
|
// 可选,获取的配额数
|
|
Token uint32
|
|
}
|
|
|
|
// GetService 获取服务名.
|
|
func (q *QuotaRequestImpl) GetService() string {
|
|
return q.service
|
|
}
|
|
|
|
// SetService 设置服务名称.
|
|
func (q *QuotaRequestImpl) SetService(svc string) {
|
|
q.service = svc
|
|
}
|
|
|
|
// GetNamespace 获取命名空间.
|
|
func (q *QuotaRequestImpl) GetNamespace() string {
|
|
return q.namespace
|
|
}
|
|
|
|
// SetNamespace 设置命名空间.
|
|
func (q *QuotaRequestImpl) SetNamespace(namespace string) {
|
|
q.namespace = namespace
|
|
}
|
|
|
|
// SetMethod set method
|
|
func (q *QuotaRequestImpl) SetMethod(method string) {
|
|
q.method = method
|
|
}
|
|
|
|
// SetToken set token
|
|
func (q *QuotaRequestImpl) SetToken(token uint32) {
|
|
q.Token = token
|
|
}
|
|
|
|
// GetToken get token
|
|
func (q *QuotaRequestImpl) GetToken() uint32 {
|
|
return q.Token
|
|
}
|
|
|
|
// SetLabels 设置业务标签.
|
|
func (q *QuotaRequestImpl) SetLabels(labels map[string]string) {
|
|
if len(labels) == 0 {
|
|
return
|
|
}
|
|
for labelKey, labelValue := range labels {
|
|
q.arguments = append(q.arguments, BuildArgumentFromLabel(labelKey, labelValue))
|
|
}
|
|
}
|
|
|
|
// GetLabels 获取业务标签.
|
|
func (q *QuotaRequestImpl) GetLabels() map[string]string {
|
|
labels := make(map[string]string, len(q.arguments))
|
|
for _, argument := range q.arguments {
|
|
argument.ToLabels(labels)
|
|
}
|
|
return labels
|
|
}
|
|
|
|
func (q *QuotaRequestImpl) GetMethod() string {
|
|
return q.method
|
|
}
|
|
|
|
// AddArgument add the match argument
|
|
func (q *QuotaRequestImpl) AddArgument(argument Argument) {
|
|
q.arguments = append(q.arguments, argument)
|
|
}
|
|
|
|
func (q *QuotaRequestImpl) Arguments() []Argument {
|
|
return q.arguments
|
|
}
|
|
|
|
// SetTimeout 设置单次查询超时时间.
|
|
func (q *QuotaRequestImpl) SetTimeout(timeout time.Duration) {
|
|
q.Timeout = &timeout
|
|
}
|
|
|
|
// SetRetryCount 设置重试次数.
|
|
func (q *QuotaRequestImpl) SetRetryCount(retryCount int) {
|
|
q.RetryCount = &retryCount
|
|
}
|
|
|
|
// GetTimeoutPtr 获取超时值指针.
|
|
func (q *QuotaRequestImpl) GetTimeoutPtr() *time.Duration {
|
|
return q.Timeout
|
|
}
|
|
|
|
// GetRetryCountPtr 获取重试次数指针.
|
|
func (q *QuotaRequestImpl) GetRetryCountPtr() *int {
|
|
return q.RetryCount
|
|
}
|
|
|
|
// Validate 校验.
|
|
func (q *QuotaRequestImpl) Validate() error {
|
|
if nil == q {
|
|
return NewSDKError(ErrCodeAPIInvalidArgument, nil, "QuotaRequestImpl can not be nil")
|
|
}
|
|
var errs error
|
|
if len(q.GetService()) == 0 {
|
|
errs = multierror.Append(errs, fmt.Errorf("QuotaRequestImpl: service is empty"))
|
|
}
|
|
if len(q.GetNamespace()) == 0 {
|
|
errs = multierror.Append(errs, fmt.Errorf("QuotaRequestImpl: namespace is empty"))
|
|
}
|
|
return errs
|
|
}
|
|
|
|
// QuotaResultCode 应答码.
|
|
type QuotaResultCode int
|
|
|
|
const (
|
|
// QuotaResultOk 应答码:成功.
|
|
QuotaResultOk QuotaResultCode = 0
|
|
// QuotaResultLimited 应答码:限制.
|
|
QuotaResultLimited QuotaResultCode = -1
|
|
)
|
|
|
|
// QuotaResponse 配额查询应答.
|
|
type QuotaResponse struct {
|
|
// 配额分配的返回码
|
|
Code QuotaResultCode
|
|
// 配额分配的结果提示信息
|
|
Info string
|
|
// 需要等待的时间段
|
|
WaitMs int64
|
|
}
|
|
|
|
// QuotaFutureImpl 异步获取配额的future.
|
|
type QuotaFutureImpl struct {
|
|
resp *QuotaResponse
|
|
deadlineCtx context.Context
|
|
cancel context.CancelFunc
|
|
}
|
|
|
|
func QuotaFutureWithResponse(resp *QuotaResponse) *QuotaFutureImpl {
|
|
var deadlineCtx context.Context
|
|
var cancel context.CancelFunc
|
|
if resp.WaitMs > 0 {
|
|
deadlineCtx, cancel = context.WithTimeout(context.Background(), time.Duration(resp.WaitMs)*time.Millisecond)
|
|
}
|
|
return &QuotaFutureImpl{
|
|
resp: resp, deadlineCtx: deadlineCtx, cancel: cancel}
|
|
}
|
|
|
|
// Done 分配是否结束.
|
|
func (q *QuotaFutureImpl) Done() <-chan struct{} {
|
|
if nil != q.deadlineCtx {
|
|
return nil
|
|
}
|
|
return q.deadlineCtx.Done()
|
|
}
|
|
|
|
func (q *QuotaFutureImpl) GetImmediately() *QuotaResponse {
|
|
return q.resp
|
|
}
|
|
|
|
// Get 获取分配结果.
|
|
func (q *QuotaFutureImpl) Get() *QuotaResponse {
|
|
if nil != q.deadlineCtx {
|
|
<-q.deadlineCtx.Done()
|
|
}
|
|
q.resp.WaitMs = 0
|
|
return q.resp
|
|
}
|
|
|
|
// Release 释放资源,仅用于并发数限流的场景.
|
|
func (q *QuotaFutureImpl) Release() {
|
|
}
|
|
|
|
const (
|
|
// RateLimitLocal 在本地限流.
|
|
RateLimitLocal = "local"
|
|
// RateLimitGlobal 在全局限流.
|
|
RateLimitGlobal = "global"
|
|
)
|
|
|
|
// ConfigMode 配置模式.
|
|
type ConfigMode int
|
|
|
|
const (
|
|
// ConfigQuotaLocalMode 在本地配置.
|
|
ConfigQuotaLocalMode ConfigMode = 0
|
|
// ConfigQuotaGlobalMode 在全局配置.
|
|
ConfigQuotaGlobalMode ConfigMode = 1
|
|
)
|