-
Notifications
You must be signed in to change notification settings - Fork 4
/
tokencache.go
82 lines (67 loc) · 1.6 KB
/
tokencache.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package sdk
import (
"context"
"sync"
"time"
)
type TokenCache interface {
Get(key string) (*Token, bool)
Set(key string, token *Token)
}
// MemoryTokenCache is a basic in-memory token cache implementation.
type MemoryTokenCache struct {
tokens map[string]*Token
lock sync.RWMutex
}
// NewMemoryTokenCache creates a new in memory token cache instance.
func NewMemoryTokenCache() *MemoryTokenCache {
return &MemoryTokenCache{
tokens: map[string]*Token{},
}
}
// Set adds or updates a token with the given key in the cache.
func (c *MemoryTokenCache) Set(key string, token *Token) {
c.lock.Lock()
defer c.lock.Unlock()
c.tokens[key] = token
}
// Get retrieves the token associated with the given key from the cache. The bool
// return value will be false if no matching key is found, and true otherwise.
func (c *MemoryTokenCache) Get(key string) (*Token, bool) {
c.lock.RLock()
token, ok := c.tokens[key]
c.lock.RUnlock()
if ok && token.Expired() {
c.lock.Lock()
delete(c.tokens, key)
c.lock.Unlock()
return nil, false
}
return token, ok
}
// StartGC starts garbage collection of expired tokens.
func (c *MemoryTokenCache) StartGC(ctx context.Context, gcInterval time.Duration) {
if gcInterval <= 0 {
return
}
ticker := time.NewTicker(gcInterval)
for {
select {
case <-ticker.C:
c.clearExpired()
case <-ctx.Done():
ticker.Stop()
return
}
}
}
// clearExpired removes all expired tokens from the cache.
func (c *MemoryTokenCache) clearExpired() {
for key, token := range c.tokens {
if token.Expired() {
c.lock.Lock()
delete(c.tokens, key)
c.lock.Unlock()
}
}
}