Skip to content

Commit b8f215c

Browse files
committed
fix(dbpurge): use dbauthz.AsSystemRestricted and add jitter
Fixes: #7016
1 parent 00d468b commit b8f215c

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

coderd/database/dbpurge/dbpurge.go

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,48 @@ import (
1010

1111
"cdr.dev/slog"
1212
"github.com/coder/coder/coderd/database"
13+
"github.com/coder/coder/coderd/database/dbauthz"
14+
"github.com/coder/coder/cryptorand"
1315
)
1416

17+
const (
18+
jitter = 2 * time.Hour
19+
delay = 23 * time.Hour
20+
)
21+
22+
func nextTick() (time.Duration, error) {
23+
f, err := cryptorand.Float64()
24+
if err != nil {
25+
return 0, err
26+
}
27+
28+
return delay + time.Duration(float64(jitter)*f), nil
29+
}
30+
1531
// New creates a new periodically purging database instance.
1632
// It is the caller's responsibility to call Close on the returned instance.
1733
//
1834
// This is for cleaning up old, unused resources from the database that take up space.
1935
func New(ctx context.Context, logger slog.Logger, db database.Store) io.Closer {
2036
closed := make(chan struct{})
2137
ctx, cancelFunc := context.WithCancel(ctx)
38+
//nolint:gocritic // The system purges old db records without user input.
39+
ctx = dbauthz.AsSystemRestricted(ctx)
2240
go func() {
2341
defer close(closed)
24-
ticker := time.NewTicker(24 * time.Hour)
25-
defer ticker.Stop()
42+
wait, err := nextTick()
43+
if err != nil {
44+
logger.Error(ctx, "failed to generate random delay; exiting", slog.Error(err))
45+
return
46+
}
47+
48+
timer := time.NewTimer(wait)
49+
defer timer.Stop()
2650
for {
2751
select {
2852
case <-ctx.Done():
2953
return
30-
case <-ticker.C:
54+
case <-timer.C:
3155
}
3256

3357
var eg errgroup.Group
@@ -44,6 +68,13 @@ func New(ctx context.Context, logger slog.Logger, db database.Store) io.Closer {
4468
}
4569
logger.Error(ctx, "failed to purge old database entries", slog.Error(err))
4670
}
71+
72+
wait, err := nextTick()
73+
if err != nil {
74+
logger.Error(ctx, "failed to generate random delay; exiting", slog.Error(err))
75+
return
76+
}
77+
timer.Reset(wait)
4778
}
4879
}()
4980
return &instance{
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package dbpurge
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func Test_nextTick(t *testing.T) {
11+
t.Parallel()
12+
13+
tick, err := nextTick()
14+
require.NoError(t, err)
15+
16+
t.Log("tick:", tick.String())
17+
18+
assert.GreaterOrEqual(t, tick, delay)
19+
assert.LessOrEqual(t, tick, delay+jitter)
20+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy