@@ -5,11 +5,11 @@ import (
5
5
"crypto/sha256"
6
6
"encoding/hex"
7
7
"encoding/json"
8
- "errors"
9
8
"fmt"
10
9
"io/ioutil"
11
10
"os"
12
11
"path/filepath"
12
+ "sync"
13
13
"time"
14
14
15
15
"github.com/faabiosr/cachego"
@@ -18,6 +18,7 @@ import (
18
18
type (
19
19
file struct {
20
20
dir string
21
+ sync.RWMutex
21
22
}
22
23
23
24
fileContent struct {
@@ -30,7 +31,7 @@ const perm = 0o666
30
31
31
32
// New creates an instance of File cache
32
33
func New (dir string ) cachego.Cache {
33
- return & file {dir }
34
+ return & file {dir : dir }
34
35
}
35
36
36
37
func (f * file ) createName (key string ) string {
@@ -42,6 +43,9 @@ func (f *file) createName(key string) string {
42
43
}
43
44
44
45
func (f * file ) read (key string ) (* fileContent , error ) {
46
+ f .RLock ()
47
+ defer f .RUnlock ()
48
+
45
49
value , err := ioutil .ReadFile (f .createName (key ))
46
50
if err != nil {
47
51
return nil , err
@@ -56,22 +60,28 @@ func (f *file) read(key string) (*fileContent, error) {
56
60
return content , nil
57
61
}
58
62
59
- if content .Duration <= time .Now ().Unix () {
60
- _ = f .Delete (key )
61
- return nil , errors .New ("cache expired" )
62
- }
63
-
64
63
return content , nil
65
64
}
66
65
67
66
// Contains checks if the cached key exists into the File storage
68
67
func (f * file ) Contains (key string ) bool {
69
- _ , err := f .read (key )
70
- return err == nil
68
+ content , err := f .read (key )
69
+ if err != nil {
70
+ return false
71
+ }
72
+
73
+ if f .isExpired (content ) {
74
+ _ = f .Delete (key )
75
+ return false
76
+ }
77
+ return true
71
78
}
72
79
73
80
// Delete the cached key from File storage
74
81
func (f * file ) Delete (key string ) error {
82
+ f .Lock ()
83
+ defer f .Unlock ()
84
+
75
85
_ , err := os .Stat (f .createName (key ))
76
86
if err != nil && os .IsNotExist (err ) {
77
87
return nil
@@ -87,9 +97,18 @@ func (f *file) Fetch(key string) (string, error) {
87
97
return "" , err
88
98
}
89
99
100
+ if f .isExpired (content ) {
101
+ _ = f .Delete (key )
102
+ return "" , cachego .ErrCacheExpired
103
+ }
104
+
90
105
return content .Data , nil
91
106
}
92
107
108
+ func (f * file ) isExpired (content * fileContent ) bool {
109
+ return content .Duration > 0 && content .Duration <= time .Now ().Unix ()
110
+ }
111
+
93
112
// FetchMulti retrieve multiple cached values from keys of the File storage
94
113
func (f * file ) FetchMulti (keys []string ) map [string ]string {
95
114
result := make (map [string ]string )
@@ -105,6 +124,9 @@ func (f *file) FetchMulti(keys []string) map[string]string {
105
124
106
125
// Flush removes all cached keys of the File storage
107
126
func (f * file ) Flush () error {
127
+ f .Lock ()
128
+ defer f .Unlock ()
129
+
108
130
dir , err := os .Open (f .dir )
109
131
if err != nil {
110
132
return err
@@ -125,14 +147,15 @@ func (f *file) Flush() error {
125
147
126
148
// Save a value in File storage by key
127
149
func (f * file ) Save (key string , value string , lifeTime time.Duration ) error {
128
- duration := int64 (0 )
150
+ f .Lock ()
151
+ defer f .Unlock ()
129
152
153
+ duration := int64 (0 )
130
154
if lifeTime > 0 {
131
155
duration = time .Now ().Unix () + int64 (lifeTime .Seconds ())
132
156
}
133
157
134
158
content := & fileContent {duration , value }
135
-
136
159
data , err := json .Marshal (content )
137
160
if err != nil {
138
161
return err
0 commit comments