Skip to content

Commit

Permalink
fixed issue where cache was not being leveraged if 200 status was not…
Browse files Browse the repository at this point in the history
… being set correctly on map and layer tile requests. added tests to catch the issue in the future. closes #263
  • Loading branch information
ARolek committed Jan 17, 2018
1 parent a5c7f37 commit 8cbf2b0
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 7 deletions.
2 changes: 1 addition & 1 deletion server/handle_map_layer_zxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (req HandleMapLayerZXY) ServeHTTP(w http.ResponseWriter, r *http.Request) {

// mimetype for protocol buffers
w.Header().Add("Content-Type", "application/x-protobuf")

w.WriteHeader(http.StatusOK)
w.Write(pbyte)

// check for tile size warnings
Expand Down
2 changes: 1 addition & 1 deletion server/handle_map_zxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func (req HandleMapZXY) ServeHTTP(w http.ResponseWriter, r *http.Request) {

// mimetype for protocol buffers
w.Header().Add("Content-Type", "application/x-protobuf")

w.WriteHeader(http.StatusOK)
w.Write(pbyte)

// check for tile size warnings
Expand Down
12 changes: 7 additions & 5 deletions server/middleware_tile_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package server
import (
"bytes"
"io"
"log"
"net/http"

"github.com/terranodo/tegola/cache"
"github.com/terranodo/tegola/internal/log"
)

// TileCacheHandler implements a request cache for tiles on requests when the URLs
Expand All @@ -27,18 +27,19 @@ func TileCacheHandler(next http.Handler) http.Handler {
// 5 is the value of len("maps/")
key, err := cache.ParseKey(r.URL.Path[5:])
if err != nil {
log.Println("cache middleware: ParseKey err: %v", err)
log.Errorf("cache middleware: ParseKey err: %v", err)
next.ServeHTTP(w, r)
return
}

// use the URL path as the key
cachedTile, hit, err := cacher.Get(key)
if err != nil {
log.Printf("cache middleware: error reading from cache: %v", err)
log.Errorf("cache middleware: error reading from cache: %v", err)
next.ServeHTTP(w, r)
return
}

// cache miss
if !hit {
// buffer which will hold a copy of the response for writing to the cache
Expand All @@ -60,7 +61,7 @@ func TileCacheHandler(next http.Handler) http.Handler {
}

if err := cacher.Set(key, buff.Bytes()); err != nil {
log.Printf("cache response writer err: %v", err)
log.Warnf("cache response writer err: %v", err)
}
return
}
Expand Down Expand Up @@ -93,7 +94,7 @@ type tileCacheResponseWriter struct {
}

func (w *tileCacheResponseWriter) Header() http.Header {
// communicate the tegola cache is being used
// communicate the cache is being used
w.resp.Header().Set("Tegola-Cache", "MISS")

return w.resp.Header()
Expand All @@ -102,6 +103,7 @@ func (w *tileCacheResponseWriter) Header() http.Header {
func (w *tileCacheResponseWriter) Write(b []byte) (int, error) {
// only write to the multi writer when http response == StatusOK
if w.status == http.StatusOK {

// write to our multi writer
return w.multi.Write(b)
}
Expand Down
49 changes: 49 additions & 0 deletions server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package server_test

import (
"context"
"sync"

"github.com/terranodo/tegola"
"github.com/terranodo/tegola/atlas"
"github.com/terranodo/tegola/basic"
"github.com/terranodo/tegola/cache"
"github.com/terranodo/tegola/mvt"
"github.com/terranodo/tegola/server"
)
Expand Down Expand Up @@ -93,6 +95,49 @@ func (l layer) SRID() int {
return l.srid
}

func NewMemoryCache() *MemoryCache {
return &MemoryCache{
keyVals: map[string][]byte{},
}
}

// test cacher, implements the cache.Interface
type MemoryCache struct {
keyVals map[string][]byte
sync.RWMutex
}

func (mc *MemoryCache) Get(key *cache.Key) ([]byte, bool, error) {
mc.RLock()
defer mc.RUnlock()

val, ok := mc.keyVals[key.String()]
if !ok {
return nil, false, nil
}

return val, true, nil
}

func (mc *MemoryCache) Set(key *cache.Key, val []byte) error {
mc.Lock()
defer mc.Unlock()

mc.keyVals[key.String()] = val

return nil
}

func (mc *MemoryCache) Purge(key *cache.Key) error {
mc.Lock()
defer mc.Unlock()

delete(mc.keyVals, key.String())

return nil
}

// pre test setup phase
func init() {
server.Version = serverVersion
server.HostName = serverHostName
Expand All @@ -106,6 +151,10 @@ func init() {
testLayer3,
}...)

atlas.SetCache(NewMemoryCache())

// register a map with atlas
atlas.AddMap(testMap)

server.Atlas = atlas.DefaultAtlas
}

0 comments on commit 8cbf2b0

Please sign in to comment.