From 95f6cf3e166d80922378807ac931517ae2fe557e Mon Sep 17 00:00:00 2001 From: Peter Sanchez Date: Thu, 25 Jan 2024 18:57:25 -0600 Subject: [PATCH] Adding base Cache interface. Very simple. Will think a bit more about any additional options to add. References: https://todo.code.netlandish.com/~netlandish/gobwebs/7 --- cache/cache.go | 48 +++++++++++++++++++++++++++++++++++++++++++++ cache/middleware.go | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 cache/cache.go create mode 100644 cache/middleware.go diff --git a/cache/cache.go b/cache/cache.go new file mode 100644 index 0000000..a5e2162 --- /dev/null +++ b/cache/cache.go @@ -0,0 +1,48 @@ +package cache + +type Cache interface { + Get(key string) (any, error) + Set(key string, value any) (bool, error) + Delete(key string) (bool, error) +} + +type DummyCache struct { + cache map[string]any + limit int +} + +func (d *DummyCache) Get(key string) (any, error) { + val := d.cache[key] + return val, nil +} + +func (d *DummyCache) Set(key string, value any) (bool, error) { + var evicted bool + if len(d.cache) >= d.limit { + for k := range d.cache { + d.Delete(k) + if len(d.cache) < d.limit { + break + } + } + evicted = true + } + d.cache[key] = value + return evicted, nil +} + +func (d *DummyCache) Delete(key string) (bool, error) { + var present bool + if _, ok := d.cache[key]; ok { + present = true + } + delete(d.cache, key) + return present, nil +} + +func NewDummyCache(limit int) *DummyCache { + return &DummyCache{ + cache: make(map[string]any), + limit: limit, + } +} diff --git a/cache/middleware.go b/cache/middleware.go new file mode 100644 index 0000000..f784ce0 --- /dev/null +++ b/cache/middleware.go @@ -0,0 +1,39 @@ +package cache + +import ( + "context" + "errors" + + "github.com/labstack/echo/v4" +) + +var cacheCtxKey = &contextKey{"cache"} + +type contextKey struct { + name string +} + +// Context adds cache manager to context for immediate use +func Context(ctx context.Context, cache Cache) context.Context { + return context.WithValue(ctx, cacheCtxKey, cache) +} + +// ForContext pulls cache manager value for context +func ForContext(ctx context.Context) Cache { + cache, ok := ctx.Value(cacheCtxKey).(Cache) + if !ok { + panic(errors.New("invalid cache context")) + } + return cache +} + +// Middleware will add the provided Cache instance to the context +func Middleware(cache Cache) echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + ctx := Context(c.Request().Context(), cache) + c.SetRequest(c.Request().WithContext(ctx)) + return next(c) + } + } +} -- 2.45.2