github.com/zorawar87/trillian@v1.2.1/quota/quota.go (about) 1 // Copyright 2017 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package quota 16 17 import ( 18 "context" 19 "fmt" 20 "strings" 21 ) 22 23 // MaxTokens is the maximum number of available tokens a quota may have. 24 const MaxTokens = int(^uint(0) >> 1) // MaxInt 25 26 // Group represents the scope of a token (Global, Tree or User). 27 type Group int 28 29 const ( 30 // Global is the Trillian-wide token scope (applies to all users and trees). 31 // A global quota shortage for a certain kind of token means all requests of that kind will 32 // be denied until the quota is replenished. 33 Global Group = iota 34 35 // Tree is the tree-wide token scope. 36 Tree 37 38 // User is the per-user token scope. 39 // Users are defined according to each implementation. 40 User 41 ) 42 43 // Kind represents the purpose of each token (Read or Write). 44 type Kind int 45 46 const ( 47 // Read represents tokens used by non-modifying RPCs. 48 Read Kind = iota 49 50 // Write represents tokens used by modifying RPCs. 51 Write 52 ) 53 54 // Spec represents a combination of Group and Kind, with all additional data required to get / put 55 // tokens. 56 type Spec struct { 57 // Group of the spec. 58 Group 59 60 // Kind of the spec. 61 Kind 62 63 // TreeID identifies the tree for specs of the Tree group. 64 // Not used for other specs. 65 TreeID int64 66 67 // User identifies the user for specs of the User group. 68 // Not used for other specs. 69 User string 70 } 71 72 // Name returns a textual representation of the Spec. Names are constant and may be relied upon to 73 // not change in the future. 74 // 75 // Names are created as follows: 76 // * Global quotas are mapped to "global/read" or "global/write" 77 // * Tree quotas are mapped to "trees/$TreeID/$Kind". E.g., "trees/10/read". 78 // * User quotas are mapped to "users/$User/$Kind". E.g., "trees/10/read". 79 func (s Spec) Name() string { 80 group := strings.ToLower(fmt.Sprint(s.Group)) 81 kind := strings.ToLower(fmt.Sprint(s.Kind)) 82 if s.Group == Global { 83 return fmt.Sprintf("%v/%v", group, kind) 84 } 85 var user string 86 switch s.Group { 87 case Tree: 88 user = fmt.Sprint(s.TreeID) 89 case User: 90 user = s.User 91 } 92 return fmt.Sprintf("%vs/%v/%v", group, user, kind) 93 } 94 95 // String returns a description of Spec. 96 func (s Spec) String() string { 97 return s.Name() 98 } 99 100 // Manager is the component responsible for the management of tokens. 101 type Manager interface { 102 // GetTokens acquires numTokens from all specs. Tokens are taken in the order specified by 103 // specs. 104 // Returns error if numTokens could not be acquired for all specs. 105 GetTokens(ctx context.Context, numTokens int, specs []Spec) error 106 107 // PeekTokens returns how many tokens are available for each spec, without acquiring any. 108 // Infinite quotas should return MaxTokens. 109 PeekTokens(ctx context.Context, specs []Spec) (map[Spec]int, error) 110 111 // PutTokens adds numTokens for all specs. 112 PutTokens(ctx context.Context, numTokens int, specs []Spec) error 113 114 // ResetQuota resets the quota for all specs. 115 ResetQuota(ctx context.Context, specs []Spec) error 116 }