Skip to content

Commit f9bff68

Browse files
committed
Refactor DBKeyCache to DBCache with clock support
- Simplify naming by renaming `DBKeyCache` to `DBCache`. - Introduce `DBCacheOption` for flexible clock configuration. - Ensure consistent clock handling across the methods.
1 parent c6fdfe6 commit f9bff68

File tree

4 files changed

+48
-46
lines changed

4 files changed

+48
-46
lines changed

coderd/cryptokeys/dbkeycache.go

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,35 @@ import (
1313
"github.com/coder/quartz"
1414
)
1515

16-
// DBKeyCache implements KeyCache for callers with access to the database.
17-
type DBKeyCache struct {
18-
Clock quartz.Clock
16+
// DBCache implements Keycache for callers with access to the database.
17+
type DBCache struct {
1918
db database.Store
2019
feature database.CryptoKeyFeature
2120
logger slog.Logger
21+
clock quartz.Clock
2222

23-
// The following are initialized by NewDBKeyCache.
23+
// The following are initialized by NewDBCache.
2424
cacheMu sync.RWMutex
2525
cache map[int32]database.CryptoKey
2626
latestKey database.CryptoKey
2727
}
2828

29-
// NewDBKeyCache creates a new DBKeyCache. It starts a background
29+
type DBCacheOption func(*DBCache)
30+
31+
func WithDBCacheClock(clock quartz.Clock) DBCacheOption {
32+
return func(d *DBCache) {
33+
d.clock = clock
34+
}
35+
}
36+
37+
// NewDBCache creates a new DBCache. It starts a background
3038
// process that periodically refreshes the cache. The context should
3139
// be canceled to stop the background process.
32-
func NewDBKeyCache(ctx context.Context, logger slog.Logger, db database.Store, feature database.CryptoKeyFeature, opts ...func(*DBKeyCache)) (*DBKeyCache, error) {
33-
d := &DBKeyCache{
40+
func NewDBCache(ctx context.Context, logger slog.Logger, db database.Store, feature database.CryptoKeyFeature, opts ...func(*DBCache)) (*DBCache, error) {
41+
d := &DBCache{
3442
db: db,
3543
feature: feature,
36-
Clock: quartz.NewReal(),
44+
clock: quartz.NewReal(),
3745
logger: logger,
3846
}
3947
for _, opt := range opts {
@@ -52,8 +60,8 @@ func NewDBKeyCache(ctx context.Context, logger slog.Logger, db database.Store, f
5260

5361
// Version returns the CryptoKey with the given sequence number, provided that
5462
// it is not deleted or has breached its deletion date.
55-
func (d *DBKeyCache) Version(ctx context.Context, sequence int32) (database.CryptoKey, error) {
56-
now := d.Clock.Now().UTC()
63+
func (d *DBCache) Version(ctx context.Context, sequence int32) (database.CryptoKey, error) {
64+
now := d.clock.Now().UTC()
5765
d.cacheMu.RLock()
5866
key, ok := d.cache[sequence]
5967
d.cacheMu.RUnlock()
@@ -96,12 +104,12 @@ func (d *DBKeyCache) Version(ctx context.Context, sequence int32) (database.Cryp
96104
return key, nil
97105
}
98106

99-
func (d *DBKeyCache) Latest(ctx context.Context) (database.CryptoKey, error) {
107+
func (d *DBCache) Latest(ctx context.Context) (database.CryptoKey, error) {
100108
d.cacheMu.RLock()
101109
latest := d.latestKey
102110
d.cacheMu.RUnlock()
103111

104-
now := d.Clock.Now().UTC()
112+
now := d.clock.Now().UTC()
105113
if latest.IsActive(now) {
106114
return latest, nil
107115
}
@@ -131,8 +139,8 @@ func (d *DBKeyCache) Latest(ctx context.Context) (database.CryptoKey, error) {
131139
return d.latestKey, nil
132140
}
133141

134-
func (d *DBKeyCache) refresh(ctx context.Context) {
135-
d.Clock.TickerFunc(ctx, time.Minute*10, func() error {
142+
func (d *DBCache) refresh(ctx context.Context) {
143+
d.clock.TickerFunc(ctx, time.Minute*10, func() error {
136144
cache, latest, err := d.newCache(ctx)
137145
if err != nil {
138146
d.logger.Error(ctx, "failed to refresh cache", slog.Error(err))
@@ -146,8 +154,8 @@ func (d *DBKeyCache) refresh(ctx context.Context) {
146154
})
147155
}
148156

149-
func (d *DBKeyCache) newCache(ctx context.Context) (map[int32]database.CryptoKey, database.CryptoKey, error) {
150-
now := d.Clock.Now().UTC()
157+
func (d *DBCache) newCache(ctx context.Context) (map[int32]database.CryptoKey, database.CryptoKey, error) {
158+
now := d.clock.Now().UTC()
151159
keys, err := d.db.GetCryptoKeysByFeature(ctx, d.feature)
152160
if err != nil {
153161
return nil, database.CryptoKey{}, xerrors.Errorf("get crypto keys by feature: %w", err)

coderd/cryptokeys/dbkeycache_internal_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ func Test_Version(t *testing.T) {
4040
32: expectedKey,
4141
}
4242

43-
k := &DBKeyCache{
43+
k := &DBCache{
4444
db: mockDB,
4545
feature: database.CryptoKeyFeatureWorkspaceApps,
4646
cache: cache,
47-
Clock: clock,
47+
clock: clock,
4848
}
4949

5050
got, err := k.Version(ctx, 32)
@@ -77,11 +77,11 @@ func Test_Version(t *testing.T) {
7777
Sequence: 33,
7878
}).Return(expectedKey, nil)
7979

80-
k := &DBKeyCache{
80+
k := &DBCache{
8181
db: mockDB,
8282
feature: database.CryptoKeyFeatureWorkspaceApps,
8383
cache: map[int32]database.CryptoKey{},
84-
Clock: clock,
84+
clock: clock,
8585
}
8686

8787
got, err := k.Version(ctx, 33)
@@ -115,11 +115,11 @@ func Test_Version(t *testing.T) {
115115
},
116116
}
117117

118-
k := &DBKeyCache{
118+
k := &DBCache{
119119
db: mockDB,
120120
feature: database.CryptoKeyFeatureWorkspaceApps,
121121
cache: cache,
122-
Clock: clock,
122+
clock: clock,
123123
}
124124

125125
_, err := k.Version(ctx, 32)
@@ -153,11 +153,11 @@ func Test_Version(t *testing.T) {
153153
Sequence: 32,
154154
}).Return(invalidKey, nil)
155155

156-
k := &DBKeyCache{
156+
k := &DBCache{
157157
db: mockDB,
158158
feature: database.CryptoKeyFeatureWorkspaceApps,
159159
cache: map[int32]database.CryptoKey{},
160-
Clock: clock,
160+
clock: clock,
161161
}
162162

163163
_, err := k.Version(ctx, 32)
@@ -187,10 +187,10 @@ func Test_Latest(t *testing.T) {
187187
},
188188
StartsAt: clock.Now().UTC(),
189189
}
190-
k := &DBKeyCache{
190+
k := &DBCache{
191191
db: mockDB,
192192
feature: database.CryptoKeyFeatureWorkspaceApps,
193-
Clock: clock,
193+
clock: clock,
194194
latestKey: latestKey,
195195
}
196196

@@ -221,10 +221,10 @@ func Test_Latest(t *testing.T) {
221221

222222
mockDB.EXPECT().GetCryptoKeysByFeature(ctx, database.CryptoKeyFeatureWorkspaceApps).Return([]database.CryptoKey{latestKey}, nil)
223223

224-
k := &DBKeyCache{
224+
k := &DBCache{
225225
db: mockDB,
226226
feature: database.CryptoKeyFeatureWorkspaceApps,
227-
Clock: clock,
227+
clock: clock,
228228
latestKey: database.CryptoKey{
229229
Feature: database.CryptoKeyFeatureWorkspaceApps,
230230
Sequence: 32,
@@ -277,10 +277,10 @@ func Test_Latest(t *testing.T) {
277277

278278
mockDB.EXPECT().GetCryptoKeysByFeature(ctx, database.CryptoKeyFeatureWorkspaceApps).Return([]database.CryptoKey{inactiveKey, activeKey}, nil)
279279

280-
k := &DBKeyCache{
280+
k := &DBCache{
281281
db: mockDB,
282282
feature: database.CryptoKeyFeatureWorkspaceApps,
283-
Clock: clock,
283+
clock: clock,
284284
cache: map[int32]database.CryptoKey{},
285285
}
286286

@@ -325,10 +325,10 @@ func Test_Latest(t *testing.T) {
325325

326326
mockDB.EXPECT().GetCryptoKeysByFeature(ctx, database.CryptoKeyFeatureWorkspaceApps).Return([]database.CryptoKey{inactiveKey, invalidKey}, nil)
327327

328-
k := &DBKeyCache{
328+
k := &DBCache{
329329
db: mockDB,
330330
feature: database.CryptoKeyFeatureWorkspaceApps,
331-
Clock: clock,
331+
clock: clock,
332332
cache: map[int32]database.CryptoKey{},
333333
}
334334

coderd/cryptokeys/dbkeycache_test.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestDBKeyCache(t *testing.T) {
3030
logger = slogtest.Make(t, nil)
3131
)
3232

33-
_, err := cryptokeys.NewDBKeyCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, withClock(clock))
33+
_, err := cryptokeys.NewDBCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, cryptokeys.WithDBCacheClock(clock))
3434
require.NoError(t, err)
3535
})
3636

@@ -57,7 +57,7 @@ func TestDBKeyCache(t *testing.T) {
5757
StartsAt: clock.Now().UTC(),
5858
})
5959

60-
k, err := cryptokeys.NewDBKeyCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, withClock(clock))
60+
k, err := cryptokeys.NewDBCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, cryptokeys.WithDBCacheClock(clock))
6161
require.NoError(t, err)
6262

6363
got, err := k.Version(ctx, key.Sequence)
@@ -85,7 +85,7 @@ func TestDBKeyCache(t *testing.T) {
8585
StartsAt: clock.Now().UTC(),
8686
})
8787

88-
k, err := cryptokeys.NewDBKeyCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, withClock(clock))
88+
k, err := cryptokeys.NewDBCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, cryptokeys.WithDBCacheClock(clock))
8989
require.NoError(t, err)
9090

9191
key := dbgen.CryptoKey(t, db, database.CryptoKey{
@@ -132,7 +132,7 @@ func TestDBKeyCache(t *testing.T) {
132132
StartsAt: clock.Now().UTC(),
133133
})
134134

135-
k, err := cryptokeys.NewDBKeyCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, withClock(clock))
135+
k, err := cryptokeys.NewDBCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, cryptokeys.WithDBCacheClock(clock))
136136
require.NoError(t, err)
137137

138138
got, err := k.Latest(ctx)
@@ -169,7 +169,7 @@ func TestDBKeyCache(t *testing.T) {
169169
},
170170
})
171171
trap := clock.Trap().TickerFunc()
172-
k, err := cryptokeys.NewDBKeyCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, withClock(clock))
172+
k, err := cryptokeys.NewDBCache(ctx, logger, db, database.CryptoKeyFeatureWorkspaceApps, cryptokeys.WithDBCacheClock(clock))
173173
require.NoError(t, err)
174174

175175
// Should be able to fetch the expiring key since it's still valid.
@@ -208,9 +208,3 @@ func TestDBKeyCache(t *testing.T) {
208208
require.ErrorIs(t, err, cryptokeys.ErrKeyNotFound)
209209
})
210210
}
211-
212-
func withClock(clock quartz.Clock) func(*cryptokeys.DBKeyCache) {
213-
return func(d *cryptokeys.DBKeyCache) {
214-
d.Clock = clock
215-
}
216-
}

coderd/cryptokeys/keycache.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55

66
"golang.org/x/xerrors"
77

8-
"github.com/coder/coder/v2/coderd/database"
8+
"github.com/coder/coder/v2/enterprise/wsproxy/wsproxysdk"
99
)
1010

1111
var ErrKeyNotFound = xerrors.New("key not found")
@@ -14,6 +14,6 @@ var ErrKeyInvalid = xerrors.New("key is invalid for use")
1414

1515
// Keycache provides an abstraction for fetching signing keys.
1616
type Keycache interface {
17-
Latest(ctx context.Context) (database.CryptoKey, error)
18-
Version(ctx context.Context, sequence int32) (database.CryptoKey, error)
17+
Latest(ctx context.Context) (wsproxysdk.CryptoKey, error)
18+
Version(ctx context.Context, sequence int32) (wsproxysdk.CryptoKey, error)
1919
}

0 commit comments

Comments
 (0)