Skip to content

Commit ed87e74

Browse files
authored
Merge branch 'main' into drop-tables
2 parents 5a9b4c4 + d6e163c commit ed87e74

File tree

8 files changed

+34
-77
lines changed

8 files changed

+34
-77
lines changed

ratelimits/limit.go

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,8 @@ type limit struct {
6969
// precomputed to avoid doing the same calculation on every request.
7070
burstOffset int64
7171

72-
// overrideKey is the key used to look up this limit in the overrides map.
73-
overrideKey string
74-
}
75-
76-
// isOverride returns true if the limit is an override.
77-
func (l *limit) isOverride() bool {
78-
return l.overrideKey != ""
72+
// isOverride is true if the limit is an override.
73+
isOverride bool
7974
}
8075

8176
// precompute calculates the emissionInterval and burstOffset for the limit.
@@ -178,11 +173,13 @@ func parseOverrideLimits(newOverridesYAML overridesYAML) (limits, error) {
178173
}
179174

180175
lim := &limit{
181-
burst: v.Burst,
182-
count: v.Count,
183-
period: v.Period,
184-
name: name,
176+
burst: v.Burst,
177+
count: v.Count,
178+
period: v.Period,
179+
name: name,
180+
isOverride: true,
185181
}
182+
lim.precompute()
186183

187184
err := validateLimit(lim)
188185
if err != nil {
@@ -196,14 +193,12 @@ func parseOverrideLimits(newOverridesYAML overridesYAML) (limits, error) {
196193
return nil, fmt.Errorf(
197194
"validating name %s and id %q for override limit %q: %w", name, id, k, err)
198195
}
199-
lim.overrideKey = joinWithColon(name.EnumString(), id)
200196
if name == CertificatesPerFQDNSet {
201197
// FQDNSet hashes are not a nice thing to ask for in a
202198
// config file, so we allow the user to specify a
203199
// comma-separated list of FQDNs and compute the hash here.
204200
id = fmt.Sprintf("%x", core.HashNames(strings.Split(id, ",")))
205201
}
206-
lim.precompute()
207202
parsed[joinWithColon(name.EnumString(), id)] = lim
208203
}
209204
}

ratelimits/limiter.go

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ type Limiter struct {
3737
source Source
3838
clk clock.Clock
3939

40-
spendLatency *prometheus.HistogramVec
41-
overrideUsageGauge *prometheus.GaugeVec
40+
spendLatency *prometheus.HistogramVec
4241
}
4342

4443
// NewLimiter returns a new *Limiter. The provided source must be safe for
@@ -52,17 +51,10 @@ func NewLimiter(clk clock.Clock, source Source, stats prometheus.Registerer) (*L
5251
}, []string{"limit", "decision"})
5352
stats.MustRegister(spendLatency)
5453

55-
overrideUsageGauge := prometheus.NewGaugeVec(prometheus.GaugeOpts{
56-
Name: "ratelimits_override_usage",
57-
Help: "Proportion of override limit used, by limit name and bucket key.",
58-
}, []string{"limit", "bucket_key"})
59-
stats.MustRegister(overrideUsageGauge)
60-
6154
return &Limiter{
62-
source: source,
63-
clk: clk,
64-
spendLatency: spendLatency,
65-
overrideUsageGauge: overrideUsageGauge,
55+
source: source,
56+
clk: clk,
57+
spendLatency: spendLatency,
6658
}, nil
6759
}
6860

@@ -284,11 +276,6 @@ func (l *Limiter) BatchSpend(ctx context.Context, txns []Transaction) (*Decision
284276
storedTAT, bucketExists := tats[txn.bucketKey]
285277
d := maybeSpend(l.clk, txn, storedTAT)
286278

287-
if txn.limit.isOverride() {
288-
utilization := float64(txn.limit.burst-d.remaining) / float64(txn.limit.burst)
289-
l.overrideUsageGauge.WithLabelValues(txn.limit.name.String(), txn.limit.overrideKey).Set(utilization)
290-
}
291-
292279
if d.allowed && (storedTAT != d.newTAT) && txn.spend {
293280
if !bucketExists {
294281
newBuckets[txn.bucketKey] = d.newTAT

ratelimits/limiter_test.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"time"
99

1010
"github.com/jmhodges/clock"
11-
"github.com/prometheus/client_golang/prometheus"
1211

1312
"github.com/letsencrypt/boulder/config"
1413
berrors "github.com/letsencrypt/boulder/errors"
@@ -60,12 +59,6 @@ func TestLimiter_CheckWithLimitOverrides(t *testing.T) {
6059
testCtx, limiters, txnBuilder, clk, testIP := setup(t)
6160
for name, l := range limiters {
6261
t.Run(name, func(t *testing.T) {
63-
// Verify our overrideUsageGauge is being set correctly. 0.0 == 0%
64-
// of the bucket has been consumed.
65-
test.AssertMetricWithLabelsEquals(t, l.overrideUsageGauge, prometheus.Labels{
66-
"limit": NewRegistrationsPerIPAddress.String(),
67-
"bucket_key": joinWithColon(NewRegistrationsPerIPAddress.EnumString(), tenZeroZeroTwo)}, 0)
68-
6962
overriddenBucketKey, err := newIPAddressBucketKey(NewRegistrationsPerIPAddress, net.ParseIP(tenZeroZeroTwo))
7063
test.AssertNotError(t, err, "should not error")
7164
overriddenLimit, err := txnBuilder.getLimit(NewRegistrationsPerIPAddress, overriddenBucketKey)
@@ -87,12 +80,6 @@ func TestLimiter_CheckWithLimitOverrides(t *testing.T) {
8780
test.AssertEquals(t, d.remaining, int64(0))
8881
test.AssertEquals(t, d.resetIn, time.Second)
8982

90-
// Verify our overrideUsageGauge is being set correctly. 1.0 == 100%
91-
// of the bucket has been consumed.
92-
test.AssertMetricWithLabelsEquals(t, l.overrideUsageGauge, prometheus.Labels{
93-
"limit_name": NewRegistrationsPerIPAddress.String(),
94-
"bucket_key": joinWithColon(NewRegistrationsPerIPAddress.EnumString(), tenZeroZeroTwo)}, 1.0)
95-
9683
// Verify our RetryIn is correct. 1 second == 1000 milliseconds and
9784
// 1000/40 = 25 milliseconds per request.
9885
test.AssertEquals(t, d.retryIn, time.Millisecond*25)

ratelimits/source_redis.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,6 @@ func (r *RedisSource) BatchSet(ctx context.Context, buckets map[string]time.Time
9999
}
100100

101101
totalLatency := r.clk.Since(start)
102-
perSetLatency := totalLatency / time.Duration(len(buckets))
103-
for range buckets {
104-
r.observeLatency("batchset_entry", perSetLatency, nil)
105-
}
106102

107103
r.observeLatency("batchset", totalLatency, nil)
108104
return nil
@@ -128,17 +124,14 @@ func (r *RedisSource) BatchSetNotExisting(ctx context.Context, buckets map[strin
128124

129125
alreadyExists := make(map[string]bool, len(buckets))
130126
totalLatency := r.clk.Since(start)
131-
perSetLatency := totalLatency / time.Duration(len(buckets))
132127
for bucketKey, cmd := range cmds {
133128
success, err := cmd.Result()
134129
if err != nil {
135-
r.observeLatency("batchsetnotexisting_entry", perSetLatency, err)
136130
return nil, err
137131
}
138132
if !success {
139133
alreadyExists[bucketKey] = true
140134
}
141-
r.observeLatency("batchsetnotexisting_entry", perSetLatency, nil)
142135
}
143136

144137
r.observeLatency("batchsetnotexisting", totalLatency, nil)
@@ -163,11 +156,6 @@ func (r *RedisSource) BatchIncrement(ctx context.Context, buckets map[string]inc
163156
}
164157

165158
totalLatency := r.clk.Since(start)
166-
perSetLatency := totalLatency / time.Duration(len(buckets))
167-
for range buckets {
168-
r.observeLatency("batchincrby_entry", perSetLatency, nil)
169-
}
170-
171159
r.observeLatency("batchincrby", totalLatency, nil)
172160
return nil
173161
}
@@ -211,7 +199,6 @@ func (r *RedisSource) BatchGet(ctx context.Context, bucketKeys []string) (map[st
211199
}
212200

213201
totalLatency := r.clk.Since(start)
214-
perEntryLatency := totalLatency / time.Duration(len(bucketKeys))
215202

216203
tats := make(map[string]time.Time, len(bucketKeys))
217204
notFoundCount := 0
@@ -224,13 +211,10 @@ func (r *RedisSource) BatchGet(ctx context.Context, bucketKeys []string) (map[st
224211
r.observeLatency("batchget", r.clk.Since(start), err)
225212
return nil, err
226213
}
227-
// Bucket key does not exist.
228-
r.observeLatency("batchget_entry", perEntryLatency, err)
229214
notFoundCount++
230215
continue
231216
}
232217
tats[bucketKeys[i]] = time.Unix(0, tatNano).UTC()
233-
r.observeLatency("batchget_entry", perEntryLatency, nil)
234218
}
235219

236220
var batchErr error

ratelimits/transaction.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ func (builder *TransactionBuilder) certificatesPerDomainCheckOnlyTransactions(re
403403
return nil, err
404404
}
405405
if accountOverride {
406-
if !perAccountLimit.isOverride() {
406+
if !perAccountLimit.isOverride {
407407
return nil, fmt.Errorf("shouldn't happen: CertificatesPerDomainPerAccount limit is not an override")
408408
}
409409
perAccountPerDomainKey, err := NewRegIdDomainBucketKey(CertificatesPerDomainPerAccount, regId, name)
@@ -481,7 +481,7 @@ func (builder *TransactionBuilder) CertificatesPerDomainSpendOnlyTransactions(re
481481
return nil, err
482482
}
483483
if accountOverride {
484-
if !perAccountLimit.isOverride() {
484+
if !perAccountLimit.isOverride {
485485
return nil, fmt.Errorf("shouldn't happen: CertificatesPerDomainPerAccount limit is not an override")
486486
}
487487
perAccountPerDomainKey, err := NewRegIdDomainBucketKey(CertificatesPerDomainPerAccount, regId, name)

ratelimits/transaction_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,29 +79,29 @@ func TestFailedAuthorizationsPerDomainPerAccountTransactions(t *testing.T) {
7979
test.AssertEquals(t, len(txns), 1)
8080
test.AssertEquals(t, txns[0].bucketKey, "4:123456789:so.many.labels.here.example.com")
8181
test.Assert(t, txns[0].checkOnly(), "should be check-only")
82-
test.Assert(t, !txns[0].limit.isOverride(), "should not be an override")
82+
test.Assert(t, !txns[0].limit.isOverride, "should not be an override")
8383

8484
// A spend-only transaction for the default per-account limit.
8585
txn, err := tb.FailedAuthorizationsPerDomainPerAccountSpendOnlyTransaction(123456789, "so.many.labels.here.example.com")
8686
test.AssertNotError(t, err, "creating transaction")
8787
test.AssertEquals(t, txn.bucketKey, "4:123456789:so.many.labels.here.example.com")
8888
test.Assert(t, txn.spendOnly(), "should be spend-only")
89-
test.Assert(t, !txn.limit.isOverride(), "should not be an override")
89+
test.Assert(t, !txn.limit.isOverride, "should not be an override")
9090

9191
// A check-only transaction for the per-account limit override.
9292
txns, err = tb.FailedAuthorizationsPerDomainPerAccountCheckOnlyTransactions(13371338, []string{"so.many.labels.here.example.com"})
9393
test.AssertNotError(t, err, "creating transactions")
9494
test.AssertEquals(t, len(txns), 1)
9595
test.AssertEquals(t, txns[0].bucketKey, "4:13371338:so.many.labels.here.example.com")
9696
test.Assert(t, txns[0].checkOnly(), "should be check-only")
97-
test.Assert(t, txns[0].limit.isOverride(), "should be an override")
97+
test.Assert(t, txns[0].limit.isOverride, "should be an override")
9898

9999
// A spend-only transaction for the per-account limit override.
100100
txn, err = tb.FailedAuthorizationsPerDomainPerAccountSpendOnlyTransaction(13371338, "so.many.labels.here.example.com")
101101
test.AssertNotError(t, err, "creating transaction")
102102
test.AssertEquals(t, txn.bucketKey, "4:13371338:so.many.labels.here.example.com")
103103
test.Assert(t, txn.spendOnly(), "should be spend-only")
104-
test.Assert(t, txn.limit.isOverride(), "should be an override")
104+
test.Assert(t, txn.limit.isOverride, "should be an override")
105105
}
106106

107107
func TestFailedAuthorizationsForPausingPerDomainPerAccountTransactions(t *testing.T) {
@@ -115,7 +115,7 @@ func TestFailedAuthorizationsForPausingPerDomainPerAccountTransactions(t *testin
115115
test.AssertNotError(t, err, "creating transaction")
116116
test.AssertEquals(t, txn.bucketKey, "8:13371338:so.many.labels.here.example.com")
117117
test.Assert(t, txn.check && txn.spend, "should be check and spend")
118-
test.Assert(t, txn.limit.isOverride(), "should be an override")
118+
test.Assert(t, txn.limit.isOverride, "should be an override")
119119
}
120120

121121
func TestCertificatesPerDomainTransactions(t *testing.T) {
@@ -153,15 +153,15 @@ func TestCertificatesPerDomainPerAccountTransactions(t *testing.T) {
153153
test.AssertEquals(t, len(txns), 1)
154154
test.AssertEquals(t, txns[0].bucketKey, "6:13371338:example.com")
155155
test.Assert(t, txns[0].checkOnly(), "should be check-only")
156-
test.Assert(t, txns[0].limit.isOverride(), "should be an override")
156+
test.Assert(t, txns[0].limit.isOverride, "should be an override")
157157

158158
// Same as above, but with multiple example.com domains.
159159
txns, err = tb.certificatesPerDomainCheckOnlyTransactions(13371338, []string{"so.many.labels.here.example.com", "z.example.com"})
160160
test.AssertNotError(t, err, "creating transactions")
161161
test.AssertEquals(t, len(txns), 1)
162162
test.AssertEquals(t, txns[0].bucketKey, "6:13371338:example.com")
163163
test.Assert(t, txns[0].checkOnly(), "should be check-only")
164-
test.Assert(t, txns[0].limit.isOverride(), "should be an override")
164+
test.Assert(t, txns[0].limit.isOverride, "should be an override")
165165

166166
// Same as above, but with different domains.
167167
txns, err = tb.certificatesPerDomainCheckOnlyTransactions(13371338, []string{"so.many.labels.here.example.com", "z.example.net"})
@@ -170,10 +170,10 @@ func TestCertificatesPerDomainPerAccountTransactions(t *testing.T) {
170170
test.AssertEquals(t, len(txns), 2)
171171
test.AssertEquals(t, txns[0].bucketKey, "6:13371338:example.com")
172172
test.Assert(t, txns[0].checkOnly(), "should be check-only")
173-
test.Assert(t, txns[0].limit.isOverride(), "should be an override")
173+
test.Assert(t, txns[0].limit.isOverride, "should be an override")
174174
test.AssertEquals(t, txns[1].bucketKey, "6:13371338:example.net")
175175
test.Assert(t, txns[1].checkOnly(), "should be check-only")
176-
test.Assert(t, txns[1].limit.isOverride(), "should be an override")
176+
test.Assert(t, txns[1].limit.isOverride, "should be an override")
177177

178178
// Two spend-only transactions, one for the global limit and one for the
179179
// per-account limit override.
@@ -183,11 +183,11 @@ func TestCertificatesPerDomainPerAccountTransactions(t *testing.T) {
183183
txns = sortTransactions(txns)
184184
test.AssertEquals(t, txns[0].bucketKey, "5:example.com")
185185
test.Assert(t, txns[0].spendOnly(), "should be spend-only")
186-
test.Assert(t, !txns[0].limit.isOverride(), "should not be an override")
186+
test.Assert(t, !txns[0].limit.isOverride, "should not be an override")
187187

188188
test.AssertEquals(t, txns[1].bucketKey, "6:13371338:example.com")
189189
test.Assert(t, txns[1].spendOnly(), "should be spend-only")
190-
test.Assert(t, txns[1].limit.isOverride(), "should be an override")
190+
test.Assert(t, txns[1].limit.isOverride, "should be an override")
191191
}
192192

193193
func TestCertificatesPerFQDNSetTransactions(t *testing.T) {
@@ -202,7 +202,7 @@ func TestCertificatesPerFQDNSetTransactions(t *testing.T) {
202202
namesHash := fmt.Sprintf("%x", core.HashNames([]string{"example.com", "example.net", "example.org"}))
203203
test.AssertEquals(t, txn.bucketKey, "7:"+namesHash)
204204
test.Assert(t, txn.checkOnly(), "should be check-only")
205-
test.Assert(t, !txn.limit.isOverride(), "should not be an override")
205+
test.Assert(t, !txn.limit.isOverride, "should not be an override")
206206
}
207207

208208
func TestNewTransactionBuilder(t *testing.T) {

web/context.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ type RequestEvent struct {
3535
Slug string `json:",omitempty"`
3636
InternalErrors []string `json:",omitempty"`
3737
Error string `json:",omitempty"`
38-
UserAgent string `json:"ua,omitempty"`
38+
// If there is an error checking the data store for our rate limits
39+
// we ignore it, but attach the error to the log event for analysis.
40+
// TODO(#7796): Treat errors from the rate limit system as normal
41+
// errors and put them into InternalErrors.
42+
IgnoredRateLimitError string `json:",omitempty"`
43+
UserAgent string `json:"ua,omitempty"`
3944
// Origin is sent by the browser from XHR-based clients.
4045
Origin string `json:",omitempty"`
4146
Extra map[string]interface{} `json:",omitempty"`

wfe2/wfe.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -784,8 +784,7 @@ func (wfe *WebFrontEndImpl) NewAccount(
784784
wfe.sendError(response, logEvent, probs.RateLimited(err.Error()), err)
785785
return
786786
} else {
787-
wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "While checking rate limits"), err)
788-
return
787+
logEvent.IgnoredRateLimitError = err.Error()
789788
}
790789
}
791790

@@ -2352,7 +2351,7 @@ func (wfe *WebFrontEndImpl) NewOrder(
23522351
wfe.sendError(response, logEvent, probs.RateLimited(err.Error()), err)
23532352
return
23542353
} else {
2355-
wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "While checking rate limits"), err)
2354+
logEvent.IgnoredRateLimitError = err.Error()
23562355
return
23572356
}
23582357
}

0 commit comments

Comments
 (0)