Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9061a1c

Browse files
committed
prevent cache slowdown during fetches
1 parent558ad30 commit9061a1c

File tree

1 file changed

+70
-48
lines changed

1 file changed

+70
-48
lines changed

‎enterprise/wsproxy/keycache.go

Lines changed: 70 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package wsproxy
33
import (
44
"context"
55
"sync"
6+
"sync/atomic"
67
"time"
78

89
"golang.org/x/xerrors"
@@ -18,16 +19,19 @@ import (
1819
var_ cryptokeys.Keycache=&CryptoKeyCache{}
1920

2021
typeCryptoKeyCachestruct {
21-
ctx context.Context
22-
cancel context.CancelFunc
23-
client*wsproxysdk.Client
24-
logger slog.Logger
25-
Clock quartz.Clock
26-
27-
keysMu sync.RWMutex
28-
keysmap[int32]codersdk.CryptoKey
29-
latest codersdk.CryptoKey
30-
closedbool
22+
refreshCtx context.Context
23+
refreshCancel context.CancelFunc
24+
client*wsproxysdk.Client
25+
logger slog.Logger
26+
Clock quartz.Clock
27+
28+
keysMu sync.RWMutex
29+
keysmap[int32]codersdk.CryptoKey
30+
latest codersdk.CryptoKey
31+
fetchLock sync.RWMutex
32+
lastFetch time.Time
33+
refresher*quartz.Timer
34+
closed atomic.Bool
3135
}
3236

3337
funcNewCryptoKeyCache(ctx context.Context,log slog.Logger,client*wsproxysdk.Client,opts...func(*CryptoKeyCache)) (*CryptoKeyCache,error) {
@@ -46,21 +50,17 @@ func NewCryptoKeyCache(ctx context.Context, log slog.Logger, client *wsproxysdk.
4650
returnnil,xerrors.Errorf("initial fetch: %w",err)
4751
}
4852
cache.keys,cache.latest=m,latest
49-
cache.ctx,cache.cancel=context.WithCancel(ctx)
50-
51-
gocache.refresh()
53+
cache.refresher=cache.Clock.AfterFunc(time.Minute*10,cache.refresh)
5254

5355
returncache,nil
5456
}
5557

5658
func (k*CryptoKeyCache)Signing(ctx context.Context) (codersdk.CryptoKey,error) {
57-
k.keysMu.RLock()
58-
59-
ifk.closed {
60-
k.keysMu.RUnlock()
59+
ifk.isClosed() {
6160
return codersdk.CryptoKey{},cryptokeys.ErrClosed
6261
}
6362

63+
k.keysMu.RLock()
6464
latest:=k.latest
6565
k.keysMu.RUnlock()
6666

@@ -69,34 +69,31 @@ func (k *CryptoKeyCache) Signing(ctx context.Context) (codersdk.CryptoKey, error
6969
returnlatest,nil
7070
}
7171

72-
k.keysMu.Lock()
73-
deferk.keysMu.Unlock()
72+
k.fetchLock.Lock()
73+
deferk.fetchLock.Unlock()
7474

75-
ifk.closed {
75+
ifk.isClosed() {
7676
return codersdk.CryptoKey{},cryptokeys.ErrClosed
7777
}
7878

79+
k.keysMu.RLock()
7980
ifk.latest.CanSign(now) {
81+
k.keysMu.RUnlock()
8082
returnk.latest,nil
8183
}
8284

83-
varerrerror
84-
k.keys,k.latest,err=k.fetch(ctx)
85+
_,latest,err:=k.fetch(ctx)
8586
iferr!=nil {
8687
return codersdk.CryptoKey{},xerrors.Errorf("fetch: %w",err)
8788
}
8889

89-
if!k.latest.CanSign(now) {
90-
return codersdk.CryptoKey{},cryptokeys.ErrKeyNotFound
91-
}
92-
93-
returnk.latest,nil
90+
returnlatest,nil
9491
}
9592

9693
func (k*CryptoKeyCache)Verifying(ctx context.Context,sequenceint32) (codersdk.CryptoKey,error) {
9794
now:=k.Clock.Now()
9895
k.keysMu.RLock()
99-
ifk.closed {
96+
ifk.isClosed() {
10097
k.keysMu.RUnlock()
10198
return codersdk.CryptoKey{},cryptokeys.ErrClosed
10299
}
@@ -110,7 +107,7 @@ func (k *CryptoKeyCache) Verifying(ctx context.Context, sequence int32) (codersd
110107
k.keysMu.Lock()
111108
deferk.keysMu.Unlock()
112109

113-
ifk.closed {
110+
ifk.isClosed() {
114111
return codersdk.CryptoKey{},cryptokeys.ErrClosed
115112
}
116113

@@ -119,13 +116,12 @@ func (k *CryptoKeyCache) Verifying(ctx context.Context, sequence int32) (codersd
119116
returnvalidKey(key,now)
120117
}
121118

122-
varerrerror
123-
k.keys,k.latest,err=k.fetch(ctx)
119+
keys,_,err:=k.fetch(ctx)
124120
iferr!=nil {
125121
return codersdk.CryptoKey{},xerrors.Errorf("fetch: %w",err)
126122
}
127123

128-
key,ok=k.keys[sequence]
124+
key,ok=keys[sequence]
129125
if!ok {
130126
return codersdk.CryptoKey{},cryptokeys.ErrKeyNotFound
131127
}
@@ -134,28 +130,50 @@ func (k *CryptoKeyCache) Verifying(ctx context.Context, sequence int32) (codersd
134130
}
135131

136132
func (k*CryptoKeyCache)refresh() {
137-
k.Clock.TickerFunc(k.ctx,time.Minute*10,func()error {
138-
kmap,latest,err:=k.fetch(k.ctx)
139-
iferr!=nil {
140-
k.logger.Error(k.ctx,"failed to fetch crypto keys",slog.Error(err))
141-
returnnil
142-
}
133+
ifk.isClosed() {
134+
return
135+
}
136+
137+
k.keysMu.RLock()
138+
ifk.Clock.Now().Sub(k.lastFetch)<time.Minute*10 {
139+
k.keysMu.Unlock()
140+
return
141+
}
142+
143+
k.fetchLock.Lock()
144+
deferk.fetchLock.Unlock()
143145

144-
k.keysMu.Lock()
145-
deferk.keysMu.Unlock()
146-
k.keys=kmap
147-
k.latest=latest
148-
returnnil
149-
})
146+
_,_,err:=k.fetch(k.refreshCtx)
147+
iferr!=nil {
148+
k.logger.Error(k.refreshCtx,"fetch crypto keys",slog.Error(err))
149+
return
150+
}
150151
}
151152

152153
func (k*CryptoKeyCache)fetch(ctx context.Context) (map[int32]codersdk.CryptoKey, codersdk.CryptoKey,error) {
154+
153155
keys,err:=k.client.CryptoKeys(ctx)
154156
iferr!=nil {
155157
returnnil, codersdk.CryptoKey{},xerrors.Errorf("get security keys: %w",err)
156158
}
157159

158-
kmap,latest:=toKeyMap(keys.CryptoKeys,k.Clock.Now())
160+
iflen(keys.CryptoKeys)==0 {
161+
returnnil, codersdk.CryptoKey{},cryptokeys.ErrKeyNotFound
162+
}
163+
164+
now:=k.Clock.Now()
165+
kmap,latest:=toKeyMap(keys.CryptoKeys,now)
166+
if!latest.CanSign(now) {
167+
returnnil, codersdk.CryptoKey{},cryptokeys.ErrKeyInvalid
168+
}
169+
170+
k.keysMu.Lock()
171+
deferk.keysMu.Unlock()
172+
173+
k.lastFetch=k.Clock.Now()
174+
k.refresher.Reset(time.Minute*10)
175+
k.keys,k.latest=kmap,latest
176+
159177
returnkmap,latest,nil
160178
}
161179

@@ -179,14 +197,18 @@ func validKey(key codersdk.CryptoKey, now time.Time) (codersdk.CryptoKey, error)
179197
returnkey,nil
180198
}
181199

200+
func (k*CryptoKeyCache)isClosed()bool {
201+
returnk.closed.Load()
202+
}
203+
182204
func (k*CryptoKeyCache)Close() {
183205
k.keysMu.Lock()
184206
deferk.keysMu.Unlock()
185207

186-
ifk.closed {
208+
ifk.isClosed() {
187209
return
188210
}
189211

190-
k.cancel()
191-
k.closed=true
212+
k.refreshCancel()
213+
k.closed.Store(true)
192214
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp