From 7fba4f579c6e87440a50a9c67ce2d156cf2441a3 Mon Sep 17 00:00:00 2001 From: Alexander Rolek Date: Mon, 16 Oct 2017 10:49:50 -0700 Subject: [PATCH] moved caching to middleware. implemented a response writer intercept strategy. the cacher interface needs to be thought about a bit more. #96 --- cache/cache.go | 5 ++-- cache/filecache/filecache.go | 19 +++++++++++++-- server/handle_map_zxy.go | 46 +++++++----------------------------- server/server.go | 2 +- 4 files changed, 30 insertions(+), 42 deletions(-) diff --git a/cache/cache.go b/cache/cache.go index 83e1821c4..074476703 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -7,9 +7,10 @@ import ( // Cacher defines a cache back end type Cacher interface { - Read(key string) (io.Reader, error) - Write(key string, value io.Reader) error + Get(key string) (io.Reader, error) + Set(key string, value io.Reader) error Purge(key string) error + GetWriter(key string) (io.Writer, error) } // InitFunc initilize a cache given a config map. diff --git a/cache/filecache/filecache.go b/cache/filecache/filecache.go index df8130dbb..7c585bbd2 100644 --- a/cache/filecache/filecache.go +++ b/cache/filecache/filecache.go @@ -57,13 +57,13 @@ type Filecache struct { Basepath string } -func (fc *Filecache) Read(key string) (io.Reader, error) { +func (fc *Filecache) Get(key string) (io.Reader, error) { path := filepath.Join(fc.Basepath, key) return os.Open(path) } -func (fc *Filecache) Write(key string, value io.Reader) error { +func (fc *Filecache) Set(key string, value io.Reader) error { var err error // build our filepath @@ -90,6 +90,21 @@ func (fc *Filecache) Write(key string, value io.Reader) error { return nil } +func (fc *Filecache) GetWriter(key string) (io.Writer, error) { + var err error + + // build our filepath + path := filepath.Join(fc.Basepath, key) + + // the key can have a directory syntax so we need to makeAll + if err = os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil { + return nil, err + } + + // create the file + return os.Create(path) +} + func (fc *Filecache) Purge(key string) error { path := filepath.Join(fc.Basepath, key) diff --git a/server/handle_map_zxy.go b/server/handle_map_zxy.go index 675504f4d..af5642617 100644 --- a/server/handle_map_zxy.go +++ b/server/handle_map_zxy.go @@ -1,9 +1,7 @@ package server import ( - "bytes" "fmt" - "io" "log" "net/http" "strconv" @@ -116,29 +114,6 @@ func (req HandleMapZXY) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - // check if we have a cache backend setup - if Cache != nil { - key := fmt.Sprintf("/%v/%v/%v.pbf", req.z, req.x, req.y) - cachedTile, err := Cache.Read(key) - if err != nil { - // TODO: this should be a debug warning - // log.Printf("cache err: %v", err) - } else { - // TODO: how configurable do we want the CORS policy to be? - // set CORS header - w.Header().Add("Access-Control-Allow-Origin", "*") - - // mimetype for protocol buffers - w.Header().Add("Content-Type", "application/x-protobuf") - - // communicate the cache is being used - w.Header().Add("Tegola-Cache", "HIT") - - io.Copy(w, cachedTile) - return - } - } - // new tile tile := tegola.Tile{ Z: req.z, @@ -177,7 +152,7 @@ func (req HandleMapZXY) ServeHTTP(w http.ResponseWriter, r *http.Request) { } if err != nil { // TODO: should we return an error to the response or just log the error? - // we can't just write to the response as the waitgroup is going to write to the respons as well + // we can't just write to the response as the waitgroup is going to write to the response as well log.Printf("Error Getting MVTLayer for tile Z: %v, X: %v, Y: %v: %v", tile.Z, tile.X, tile.Y, err) return } @@ -243,18 +218,15 @@ func (req HandleMapZXY) ServeHTTP(w http.ResponseWriter, r *http.Request) { if len(pbyte) > MaxTileSize { log.Printf("tile z:%v, x:%v, y:%v is rather large - %v", tile.Z, tile.X, tile.Y, len(pbyte)) } - - // check if we have a cache - if Cache != nil { - key := fmt.Sprintf("/%v/%v/%v.pbf", req.z, req.x, req.y) - r := bytes.NewReader(pbyte) - - // write to our cache - if err := Cache.Write(key, r); err != nil { - log.Printf("cache err: %v", err) + /* + // check if we have a cache + if Cache != nil { + // write to our cache using the url path as the key + if err := Cache.Set(r.URL.Path, bytes.NewReader(pbyte)); err != nil { + log.Printf("cache err: %v", err) + } } - } - + */ // log the request L.Log(logItem{ X: tile.X, diff --git a/server/server.go b/server/server.go index a4fca60dd..c8e3a6616 100644 --- a/server/server.go +++ b/server/server.go @@ -59,7 +59,7 @@ func Start(port string) { group.UsingContext().Handler("OPTIONS", "/capabilities/:map_name", HandleMapCapabilities{}) // map tiles - group.UsingContext().Handler("GET", "/maps/:map_name/:z/:x/:y", HandleMapZXY{}) + group.UsingContext().Handler("GET", "/maps/:map_name/:z/:x/:y", CacheHandler(HandleMapZXY{})) group.UsingContext().Handler("OPTIONS", "/maps/:map_name/:z/:x/:y", HandleMapZXY{}) group.UsingContext().Handler("GET", "/maps/:map_name/style.json", HandleMapStyle{})