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  }