@@ -18,14 +18,37 @@ type (
18
18
19
19
storageMem struct {
20
20
sync.RWMutex
21
- store map [string ]memStorageSecret
21
+ store map [string ]memStorageSecret
22
+ storePruneTimer * time.Ticker
22
23
}
23
24
)
24
25
25
26
// New creates a new In-Mem storage
26
27
func New () storage.Storage {
27
- return & storageMem {
28
- store : make (map [string ]memStorageSecret ),
28
+ store := & storageMem {
29
+ store : make (map [string ]memStorageSecret ),
30
+ storePruneTimer : time .NewTicker (time .Minute ),
31
+ }
32
+
33
+ go store .storePruner ()
34
+
35
+ return store
36
+ }
37
+
38
+ func (s * storageMem ) storePruner () {
39
+ for range s .storePruneTimer .C {
40
+ s .pruneStore ()
41
+ }
42
+ }
43
+
44
+ func (s * storageMem ) pruneStore () {
45
+ s .Lock ()
46
+ defer s .Unlock ()
47
+
48
+ for k , v := range s .store {
49
+ if v .hasExpired () {
50
+ delete (s .store , k )
51
+ }
29
52
}
30
53
}
31
54
@@ -68,9 +91,16 @@ func (s *storageMem) ReadAndDestroy(id string) (string, error) {
68
91
69
92
defer delete (s .store , id )
70
93
71
- if ! secret .Expiry .IsZero () && secret .Expiry .Before (time .Now ()) {
94
+ // Still check to see if the secret has expired in order to prevent a
95
+ // race condition where a secret has expired but the the store pruner has
96
+ // not yet been invoked.
97
+ if secret .hasExpired () {
72
98
return "" , storage .ErrSecretNotFound
73
99
}
74
100
75
101
return secret .Secret , nil
76
102
}
103
+
104
+ func (m * memStorageSecret ) hasExpired () bool {
105
+ return ! m .Expiry .IsZero () && m .Expiry .Before (time .Now ())
106
+ }
0 commit comments