mirror of https://github.com/tikv/client-go.git
188 lines
6.6 KiB
Go
188 lines
6.6 KiB
Go
// Copyright 2023 TiKV Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// 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 util
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
)
|
|
|
|
// RequestSourceTypeKeyType is a dummy type to avoid naming collision in context.
|
|
type RequestSourceTypeKeyType struct{}
|
|
|
|
// RequestSourceTypeKey is used as the key of request source type in context.
|
|
var RequestSourceTypeKey = RequestSourceTypeKeyType{}
|
|
|
|
// RequestSourceKeyType is a dummy type to avoid naming collision in context.
|
|
type RequestSourceKeyType struct{}
|
|
|
|
// RequestSourceKey is used as the key of request source type in context.
|
|
var RequestSourceKey = RequestSourceKeyType{}
|
|
|
|
const (
|
|
// InternalTxnOthers is the type of requests that consume low resources.
|
|
// This reduces the size of metrics.
|
|
InternalTxnOthers = "others"
|
|
// InternalTxnGC is the type of GC txn.
|
|
InternalTxnGC = "gc"
|
|
// InternalTxnMeta is the type of the miscellaneous meta usage.
|
|
InternalTxnMeta = InternalTxnOthers
|
|
)
|
|
|
|
// explicit source types.
|
|
const (
|
|
ExplicitTypeEmpty = ""
|
|
ExplicitTypeLightning = "lightning"
|
|
ExplicitTypeBR = "br"
|
|
ExplicitTypeDumpling = "dumpling"
|
|
ExplicitTypeBackground = "background"
|
|
ExplicitTypeDDL = "ddl"
|
|
ExplicitTypeStats = "stats"
|
|
)
|
|
|
|
// ExplicitTypeList is the list of all explicit source types.
|
|
var ExplicitTypeList = []string{ExplicitTypeEmpty, ExplicitTypeLightning, ExplicitTypeBR, ExplicitTypeDumpling, ExplicitTypeBackground, ExplicitTypeDDL, ExplicitTypeStats}
|
|
|
|
const (
|
|
// InternalRequest is the scope of internal queries
|
|
InternalRequest = "internal"
|
|
// InternalRequestPrefix is the prefix of internal queries
|
|
InternalRequestPrefix = "internal_"
|
|
// ExternalRequest is the scope of external queries
|
|
ExternalRequest = "external"
|
|
// SourceUnknown keeps same with the default value(empty string)
|
|
SourceUnknown = "unknown"
|
|
)
|
|
|
|
// RequestSource contains the source label of the request, used for tracking resource consuming.
|
|
type RequestSource struct {
|
|
RequestSourceInternal bool
|
|
RequestSourceType string
|
|
// ExplicitRequestSourceType is a type that is set from the session variable and may be specified by the client or users.
|
|
// It is a complement to the RequestSourceType and provides additional information about how a request was initiated.
|
|
ExplicitRequestSourceType string
|
|
}
|
|
|
|
// SetRequestSourceInternal sets the scope of the request source.
|
|
func (r *RequestSource) SetRequestSourceInternal(internal bool) {
|
|
r.RequestSourceInternal = internal
|
|
}
|
|
|
|
// SetRequestSourceType sets the type of the request source.
|
|
func (r *RequestSource) SetRequestSourceType(tp string) {
|
|
r.RequestSourceType = tp
|
|
}
|
|
|
|
// SetExplicitRequestSourceType sets the type of the request source.
|
|
func (r *RequestSource) SetExplicitRequestSourceType(tp string) {
|
|
r.ExplicitRequestSourceType = tp
|
|
}
|
|
|
|
// WithInternalSourceType create context with internal source.
|
|
func WithInternalSourceType(ctx context.Context, source string) context.Context {
|
|
return context.WithValue(ctx, RequestSourceKey, RequestSource{
|
|
RequestSourceInternal: true,
|
|
RequestSourceType: source,
|
|
})
|
|
}
|
|
|
|
// WithInternalSourceAndTaskType create context with internal source and task name.
|
|
func WithInternalSourceAndTaskType(ctx context.Context, source, taskName string) context.Context {
|
|
return context.WithValue(ctx, RequestSourceKey, RequestSource{
|
|
RequestSourceInternal: true,
|
|
RequestSourceType: source,
|
|
ExplicitRequestSourceType: taskName,
|
|
})
|
|
}
|
|
|
|
// BuildRequestSource builds a request_source from internal, source and explicitSource.
|
|
func BuildRequestSource(internal bool, source, explicitSource string) string {
|
|
requestSource := RequestSource{
|
|
RequestSourceInternal: internal,
|
|
RequestSourceType: source,
|
|
ExplicitRequestSourceType: explicitSource,
|
|
}
|
|
return requestSource.GetRequestSource()
|
|
}
|
|
|
|
// IsRequestSourceInternal checks whether the input request source type is internal type.
|
|
func IsRequestSourceInternal(reqSrc *RequestSource) bool {
|
|
isInternal := false
|
|
if reqSrc != nil && IsInternalRequest(reqSrc.GetRequestSource()) {
|
|
isInternal = true
|
|
}
|
|
return isInternal
|
|
}
|
|
|
|
// GetRequestSource gets the request_source field of the request.
|
|
func (r *RequestSource) GetRequestSource() string {
|
|
source := SourceUnknown
|
|
origin := ExternalRequest
|
|
if r == nil || (len(r.RequestSourceType) == 0 && len(r.ExplicitRequestSourceType) == 0) {
|
|
// if r.RequestSourceType and r.ExplicitRequestSourceType are not set, it's mostly possible that r.RequestSourceInternal is not set
|
|
// to avoid internal requests be marked as external(default value), return unknown source here.
|
|
return source
|
|
}
|
|
if r.RequestSourceInternal {
|
|
origin = InternalRequest
|
|
}
|
|
labelList := make([]string, 0, 3)
|
|
labelList = append(labelList, origin)
|
|
if len(r.RequestSourceType) > 0 {
|
|
source = r.RequestSourceType
|
|
}
|
|
labelList = append(labelList, source)
|
|
if len(r.ExplicitRequestSourceType) > 0 && r.ExplicitRequestSourceType != r.RequestSourceType {
|
|
labelList = append(labelList, r.ExplicitRequestSourceType)
|
|
}
|
|
|
|
return strings.Join(labelList, "_")
|
|
}
|
|
|
|
// RequestSourceFromCtx extract source from passed context.
|
|
func RequestSourceFromCtx(ctx context.Context) string {
|
|
if source := ctx.Value(RequestSourceKey); source != nil {
|
|
rs := source.(RequestSource)
|
|
return rs.GetRequestSource()
|
|
}
|
|
return SourceUnknown
|
|
}
|
|
|
|
// IsInternalRequest returns the type of the request source.
|
|
func IsInternalRequest(source string) bool {
|
|
return strings.HasPrefix(source, InternalRequest)
|
|
}
|
|
|
|
// ResourceGroupNameKeyType is the context key type of resource group name.
|
|
type resourceGroupNameKeyType struct{}
|
|
|
|
// ResourceGroupNameKey is used as the key of request source type in context.
|
|
var resourceGroupNameKey = resourceGroupNameKeyType{}
|
|
|
|
// WithResourceGroupName return a copy of the given context with a associated
|
|
// resource group name.
|
|
func WithResourceGroupName(ctx context.Context, groupName string) context.Context {
|
|
return context.WithValue(ctx, resourceGroupNameKey, groupName)
|
|
}
|
|
|
|
// ResourceGroupNameFromCtx extract resource group name from passed context,
|
|
// empty string is returned is the key is not set.
|
|
func ResourceGroupNameFromCtx(ctx context.Context) string {
|
|
if val := ctx.Value(resourceGroupNameKey); val != nil {
|
|
return val.(string)
|
|
}
|
|
return ""
|
|
}
|