~netlandish/gobwebs

95f6cf3e166d80922378807ac931517ae2fe557e — Peter Sanchez 9 months ago 889c46d
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
2 files changed, 87 insertions(+), 0 deletions(-)

A cache/cache.go
A cache/middleware.go
A cache/cache.go => cache/cache.go +48 -0
@@ 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,
	}
}

A cache/middleware.go => cache/middleware.go +39 -0
@@ 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)
		}
	}
}