Skip to content

Commit

Permalink
beatlabs#128 refactor cache logic to separate package
Browse files Browse the repository at this point in the history
Signed-off-by: Vangelis Katikaridis <[email protected]>
  • Loading branch information
drakos74 committed May 9, 2020
1 parent 6b04ff6 commit e68d2a3
Show file tree
Hide file tree
Showing 15 changed files with 483 additions and 365 deletions.
40 changes: 20 additions & 20 deletions component/http/cache.go → component/http/cache/cache.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package http
package cache

import (
"fmt"
"hash/crc32"
"net/http"
"strconv"
"strings"
"time"

"github.com/beatlabs/patron/cache"

"github.com/beatlabs/patron/log"
)

Expand All @@ -22,20 +22,20 @@ const (
// minFreshValidation represents a validation , happening due to min-fresh Header requirements
minFreshValidation

// cacheControlHeader is the Header key for cache related values
// HeaderCacheControl is the Header key for cache related values
// note : it is case-sensitive
cacheControlHeader = "Cache-Control"
HeaderCacheControl = "Cache-Control"
HeaderETagHeader = "Etag"

cacheControlMinFresh = "min-fresh"
cacheControlNoCache = "no-cache"
cacheControlNoStore = "no-store"
cacheControlOnlyIfCached = "only-if-cached"
cacheControlEmpty = ""

cacheHeaderMustRevalidate = "must-revalidate"
cacheHeaderMaxAge = "max-age"
cacheHeaderETagHeader = "ETag"
cacheHeaderWarning = "Warning"
headerCacheMaxAge = "max-age"
headerMustRevalidate = "must-revalidate"
headerWarning = "Warning"
)

var metrics cacheMetrics
Expand All @@ -44,13 +44,13 @@ func init() {
metrics = newPrometheusMetrics()
}

// timeInstant is a timing function
// TimeInstant is a timing function
// returns the current time instant of the system's clock
// by default it can be `time.Now().Unix()` ,
// but for testing purposes we want to control the time
type timeInstant func() int64
type TimeInstant func() int64

var now timeInstant = func() int64 {
var Now TimeInstant = func() int64 {
return time.Now().Unix()
}

Expand Down Expand Up @@ -81,7 +81,7 @@ func cacheHandler(exec executor, rc *RouteCache) func(request *cacheHandlerReque

return func(request *cacheHandlerRequest) (response *CacheHandlerResponse, e error) {

now := now()
now := Now()

key := request.getKey()

Expand Down Expand Up @@ -216,13 +216,13 @@ func saveToCache(path, key string, rsp *CachedResponse, cache cache.TTLCache, ma
}

// addResponseHeaders adds the appropriate headers according to the CachedResponse conditions
func addResponseHeaders(now int64, header map[string]string, rsp *CachedResponse, maxAge int64) {
header[cacheHeaderETagHeader] = rsp.Etag
header[cacheControlHeader] = createCacheControlHeader(maxAge, now-rsp.LastValid)
func addResponseHeaders(now int64, header http.Header, rsp *CachedResponse, maxAge int64) {
header.Set(HeaderETagHeader, rsp.Etag)
header.Set(HeaderCacheControl, createCacheControlHeader(maxAge, now-rsp.LastValid))
if rsp.Warning != "" && rsp.FromCache {
header[cacheHeaderWarning] = rsp.Warning
header.Set(headerWarning, rsp.Warning)
} else {
delete(header, cacheHeaderWarning)
delete(header, headerWarning)
}
}

Expand All @@ -239,7 +239,7 @@ func extractRequestHeaders(header string, minAge, maxFresh int64) *cacheControl
keyValue := strings.Split(header, "=")
headerKey := strings.ToLower(keyValue[0])
switch headerKey {
case cacheHeaderMaxAge:
case headerCacheMaxAge:
/**
Indicates that the client is willing to accept a Response whose
age is no greater than the specified time in seconds. Unless max-
Expand Down Expand Up @@ -323,9 +323,9 @@ func generateETag(key []byte, t int) string {
func createCacheControlHeader(ttl, lastValid int64) string {
mAge := ttl - lastValid
if mAge < 0 {
return cacheHeaderMustRevalidate
return headerMustRevalidate
}
return fmt.Sprintf("%s=%d", cacheHeaderMaxAge, ttl-lastValid)
return fmt.Sprintf("%s=%d", headerCacheMaxAge, ttl-lastValid)
}

func min(value, threshold int64) (int64, bool) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package http
package cache

import "github.com/prometheus/client_golang/prometheus"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package http
package cache

import (
"encoding/json"
Expand All @@ -17,7 +17,7 @@ type cacheHandlerRequest struct {
func toCacheHandlerRequest(req *http.Request) *cacheHandlerRequest {
var header string
if req.Header != nil {
header = req.Header.Get(cacheControlHeader)
header = req.Header.Get(HeaderCacheControl)
}
var path string
var query string
Expand All @@ -40,7 +40,7 @@ func (c *cacheHandlerRequest) getKey() string {
// CacheHandlerResponse is the dedicated Response object for the cache handler
type CacheHandlerResponse struct {
Bytes []byte
Header map[string]string
Header http.Header
}

// CachedResponse is the struct representing an object retrieved or ready to be put into the route cache
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package http
package cache

import (
"testing"
Expand Down Expand Up @@ -47,7 +47,7 @@ func assertForCacheHandlerResponse(t *testing.T, payload interface{}) {
response := CachedResponse{
Response: CacheHandlerResponse{
Bytes: bp,
Header: map[string]string{"header": "header-value"},
Header: map[string][]string{"header": {"header-value"}},
},
LastValid: 10,
Etag: "",
Expand Down
Loading

0 comments on commit e68d2a3

Please sign in to comment.