go.temporal.io/server@v1.23.0/common/quotas/cluster_aware_quota_calculator.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package quotas 26 27 type ( 28 // MemberCounter returns the total number of instances there are for a given service. 29 MemberCounter interface { 30 MemberCount() int 31 } 32 // ClusterAwareQuotaCalculator calculates the available quota for the current host based on the per instance and per 33 // cluster quota. The quota could represent requests per second, total number of active requests, etc. It works by 34 // dividing the per cluster quota by the total number of instances running the same service. 35 ClusterAwareQuotaCalculator quotaCalculator[func() int] 36 // ClusterAwareNamespaceSpecificQuotaCalculator is similar to ClusterAwareQuotaCalculator, but it uses quotas that 37 // are specific to a namespace. 38 ClusterAwareNamespaceSpecificQuotaCalculator quotaCalculator[func(namespace string) int] 39 // quotaCalculator is a generic type that we use because the quota functions could be namespace specific or not. 40 quotaCalculator[T any] struct { 41 MemberCounter MemberCounter 42 // PerInstanceQuota is a function that returns the per instance limit. 43 PerInstanceQuota T 44 // GlobalQuota is a function that returns the per cluster limit. 45 GlobalQuota T 46 } 47 ) 48 49 // getQuota returns the effective resource limit for a host given the per instance and per cluster 50 // limits. The "resource" here could be requests per second, total number of active requests, etc. The cluster-wide 51 // limit is used if and only if it is configured to a value greater than zero and the number of instances that 52 // the memberCounter reports is greater than zero. Otherwise, the per-instance limit is used. 53 func getQuota(memberCounter MemberCounter, instanceLimit, clusterLimit int) float64 { 54 if clusterLimit > 0 && memberCounter != nil { 55 if clusterSize := memberCounter.MemberCount(); clusterSize > 0 { 56 return float64(clusterLimit) / float64(clusterSize) 57 } 58 } 59 60 return float64(instanceLimit) 61 } 62 63 func (l ClusterAwareQuotaCalculator) GetQuota() float64 { 64 return getQuota(l.MemberCounter, l.PerInstanceQuota(), l.GlobalQuota()) 65 } 66 67 func (l ClusterAwareNamespaceSpecificQuotaCalculator) GetQuota(namespace string) float64 { 68 return getQuota(l.MemberCounter, l.PerInstanceQuota(namespace), l.GlobalQuota(namespace)) 69 }