diff --git a/api/v1/server.go b/api/v1/server.go index 1380c97..0fcc0e3 100644 --- a/api/v1/server.go +++ b/api/v1/server.go @@ -3,6 +3,7 @@ package api_v1 import ( "context" "net/http" + "time" "git.ar21.de/yolokube/country-geo-locations/pkg/geoloc" "github.com/go-chi/chi/v5" @@ -49,16 +50,20 @@ func searchIPCtx(next http.Handler) http.Handler { render.Render(w, r, errInvalidRequest(err)) return } - for { - ipinfo, err = geoloc.SearchIPNet(ipnetnum) - if err != nil { - render.Render(w, r, errNotFound) - return - } - if ipinfo != nil { - break - } - ipnetnum = ipnetnum - 8 + + newipnet, found := geoloc.IPCache.Get(ipnetnum) + if found { + ipnetnum = newipnet + } + + ipinfo, err = geoloc.SearchIPNet(ipnetnum) + if err != nil { + render.Render(w, r, errNotFound) + return + } + + if !found { + geoloc.IPCache.Set(ipnetnum, ipinfo.IPNumFrom, 2*time.Minute) } } ctx := context.WithValue(r.Context(), keyIPInfo, ipinfo) diff --git a/main.go b/main.go index e1da3ab..2aba800 100644 --- a/main.go +++ b/main.go @@ -32,6 +32,9 @@ func main() { } fmt.Println("Import data from file successful") + geoloc.IPCache = geoloc.NewCache() + fmt.Println("Cache created") + r := chi.NewRouter() r.Use(middleware.RequestID) r.Use(middleware.Logger) diff --git a/pkg/geoloc/cache.go b/pkg/geoloc/cache.go new file mode 100644 index 0000000..6b29b9d --- /dev/null +++ b/pkg/geoloc/cache.go @@ -0,0 +1,29 @@ +package geoloc + +import ( + "sync" + "time" +) + +var IPCache *Cache + +type Cache struct { + store sync.Map +} + +func NewCache() *Cache { + return &Cache{} +} + +func (c *Cache) Set(key, value uint, ttl time.Duration) { + c.store.Store(key, value) + time.AfterFunc(ttl, func() { + c.store.Delete(key) + }) +} + +func (c *Cache) Get(key uint) (uint, bool) { + output, _ := c.store.Load(key) + value, ok := output.(uint) + return value, ok +}