Skip to content

Commit de9274d

Browse files
committed
Added mutex for cache read/write operations
1 parent e4552f4 commit de9274d

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

cache.go

+33-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"bytes"
66
"log"
77
"net/http"
8+
"sync"
89
"time"
910
)
1011

@@ -13,6 +14,7 @@ import (
1314
// Response are indexed by the request URL path and are stored
1415
// only if they contain the "Expires" header.
1516
type CacheMiddleware struct {
17+
mutex sync.RWMutex
1618
cache map[string]*cachedResponse
1719
}
1820

@@ -33,17 +35,22 @@ func NewCacheMiddleware() *CacheMiddleware {
3335
func (c *CacheMiddleware) ProcessRequest(rw http.ResponseWriter, req *http.Request) {
3436
log.Printf("Processing request for: '%v'", req.URL.Path)
3537

36-
entry, ok := c.cache[req.URL.Path]
38+
cached, ok := c.get(req.URL.Path)
3739

38-
// Response is not on cache or already expired
39-
if !ok || entry.expires <= time.Now().Unix() {
40+
// Response is not on cache
41+
if !ok {
4042
setCacheStatus(rw, "MISS")
41-
delete(c.cache, req.URL.Path) // not necessary?
43+
return
44+
}
45+
// Response in cache expired
46+
if cached.expires <= time.Now().Unix() {
47+
setCacheStatus(rw, "MISS")
48+
c.delete(req.URL.Path)
4249
return
4350
}
4451

4552
// Read cached response
46-
res, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(entry.responseData)), req)
53+
res, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(cached.responseData)), req)
4754
if err != nil {
4855
log.Printf("Error reading response stored in cache: %v", err)
4956
setCacheStatus(rw, "MISS")
@@ -72,7 +79,27 @@ func (c *CacheMiddleware) ProcessResponse(res *http.Response, req *http.Request)
7279
}
7380

7481
b := DumpResponse(res)
75-
c.cache[req.URL.Path] = &cachedResponse{responseData: b.Bytes(), expires: t.Unix()}
82+
83+
c.update(req.URL.Path, &cachedResponse{responseData: b.Bytes(), expires: t.Unix()})
84+
}
85+
86+
func (c *CacheMiddleware) get(URLPath string) (entry *cachedResponse, ok bool) {
87+
c.mutex.RLock()
88+
defer c.mutex.RUnlock()
89+
entry, ok = c.cache[URLPath]
90+
return
91+
}
92+
93+
func (c *CacheMiddleware) update(URLPath string, response *cachedResponse) {
94+
c.mutex.Lock()
95+
defer c.mutex.Unlock()
96+
c.cache[URLPath] = response
97+
}
98+
99+
func (c *CacheMiddleware) delete(URLPath string) {
100+
c.mutex.Lock()
101+
defer c.mutex.Unlock()
102+
delete(c.cache, URLPath)
76103
}
77104

78105
func setCacheStatus(rw http.ResponseWriter, status string) {

0 commit comments

Comments
 (0)