go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/server/quota/quotapb/policy.proto (about) 1 // Copyright 2022 The LUCI Authors. All rights reserved. 2 // Use of this source code is governed under the Apache License, Version 2.0 3 // that can be found in the LICENSE file. 4 5 syntax = "proto3"; 6 7 import "validate/validate.proto"; 8 import "google/protobuf/duration.proto"; 9 10 option go_package = "go.chromium.org/luci/server/quota/quotapb"; 11 12 package go.chromium.org.luci.server.quota.quotapb; 13 14 // A Policy represents a single quota policy. 15 // 16 // A single Policy will typically be used to govern many Accounts. 17 // 18 // Policies are always loaded into the database within a PolicyConfig. 19 message Policy { 20 // The number of resources to assign to an Account when first accessed under 21 // this Policy. 22 // 23 // Must be <= `limit`. 24 uint64 default = 1 [ 25 (validate.rules).uint64.lte = 9007199254740991 26 ]; 27 28 // The maximum balance of Accounts managed under this Policy. 29 // 30 // Operations with a positive delta will be capped to this value, unless they 31 // specify `POLICY_HARD_LIMIT`, in which case exceeding this limit will be an 32 // error. 33 // 34 // If this policy has a positive refill, accounts with this policy will 35 // gradually fill to this limit over time (but will never refill past it). 36 // 37 // NOTE: When assigning a new Policy to an existing Account it's possible for 38 // an Account balance to exceed this value. 39 // 40 // For example, say an Account had a balance of 100 under a Policy with 41 // a limit of 100, but then you set a new Policy with a limit of 50. In this 42 // case, the Account balance remains at 100. However, the Account would not 43 // gain any additional refill under the new Policy until it was brought below 44 // 50 (the new limit). 45 // 46 // This is done because applications using the quota library may not have full 47 // consistency with their Policy choice (e.g. they may choose a Policy based 48 // on group membership, which is volatile, or some application nodes may have 49 // gotten configuration to use a new Policy version while others haven't). 50 uint64 limit = 2 [ 51 (validate.rules).uint64.lte = 9007199254740991 52 ]; 53 54 // Refill describes how Accounts under this Policy refill (or drain) over 55 // time. 56 // 57 // The Refill process mimics a cron, starting at UTC midnight + offset, waking 58 // up every `interval` seconds to add `units` to the Account balance (up to 59 // `limit`). This refill operation only happens when an Account is actually 60 // interacted with, however. 61 message Refill { 62 // The number of units to add to the Account banance every `interval`. 63 // 64 // The refill process is discrete; From T0..T0+interval, none of 65 // these units will appear in the Account balance. At T0+interval, all 66 // the units will be added. 67 // 68 // Note that it's permitted to have a negative refill `units` to have 69 // Account balances drain back to 0 over time. 70 // 71 // It's not permitted for the units to be 0 (just omit the Refill message 72 // entirely in that case). 73 int64 units = 1 [(validate.rules).int64 = { 74 gte: -9007199254740991 75 not_in: 0 76 lte: 9007199254740991 77 }]; 78 79 // The number of seconds between refill events, synchronized to UTC midnight 80 // + `offset`. 81 // 82 // If this is 0 and `units` is positive, the Account will be treated as if 83 // it always has `limit` quota. 84 // 85 // It is an error for this to be 0 with negative `units`. To achieve this, 86 // just make a Policy with a limit of 0 and no Refill. 87 // 88 // Refill events occur synchronized to "midnight" in UTC. So if you set this 89 // to 60, then each minute-after-UTC-midnight, the Account will gain 90 // `units`. This synchronization makes quota Account refill more 91 // predictable. 92 // 93 // The offset from UTC is currently configed on the Policy (i.e. to support 94 // policies which are synched with different time zones), but this 95 // presumably could instead be configured on a per-Account basis, if it were 96 // needed. 97 // 98 // This MUST evenly divide 24h (86400). For example, an interval of 71 is 99 // NOT OK because it would divide the day into 1216.9 intervals, meaning 100 // that the refresh 'cycle' could not correctly reset at midnight every day. 101 // An interval of 72 IS ok though, because it evenly divides the day into 102 // 1200 refresh periods. 103 uint32 interval = 2 [ 104 (validate.rules).uint32.lte = 86400 // 24h 105 ]; 106 107 // An offset from UTC midnight. This will be used to establish when the 108 // associated Accounts 'start their day', and can be used to implement 109 // a rudimentary timezone alignment for quota Accounts. 110 uint32 offset = 3 [ 111 (validate.rules).uint32.lte = 86400 // 24h 112 ]; 113 } 114 Refill refill = 3; 115 116 enum Options { 117 NO_OPTIONS = 0; 118 119 // Indicates that this Policy covers a resource type which represents an 120 // absolute quantity (e.g. number of builds in flight, current amount of 121 // storage used, etc.). Accounts flagged with this option cannot be manually 122 // manipulated via the Admin API, even with `quota.accounts.write` 123 // permission. Applications which need to expose 'reset' functionality for 124 // these should expose their own endpoints for this (or, ideally, don't 125 // allow these Accounts to get out of sync with reality in the first place 126 // :)) 127 ABSOLUTE_RESOURCE = 1; 128 } 129 // Bitwise-OR of Options values. 130 int32 options = 4; 131 132 // The amount of time that Accounts created with this Policy should persist 133 // after being written. Each Op on the Account refreshes the timeout. 134 // 135 // This could be used to create temporary quota Accounts based on e.g. IP 136 // address which automatically garbage collect after a certain time. 137 // 138 // A value of 0 means an 'infinite' Account lifetime (the default). 139 // It's recommended to pick some very large value for this rather than 0, to 140 // allow Redis to prune old Accounts when it needs to do garbage collection. 141 google.protobuf.Duration lifetime = 5; 142 }