feat: improve perf by caching proxy and layers locally
This commit is contained in:
6
internal/cache/cache.go
vendored
Normal file
6
internal/cache/cache.go
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
package cache
|
||||
|
||||
type Cache[K comparable, V any] interface {
|
||||
Get(key K) (V, bool)
|
||||
Set(key K, value V)
|
||||
}
|
34
internal/cache/memory/cache.go
vendored
Normal file
34
internal/cache/memory/cache.go
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
cache "forge.cadoles.com/cadoles/bouncer/internal/cache"
|
||||
)
|
||||
|
||||
type Cache[K comparable, V any] struct {
|
||||
store *sync.Map
|
||||
}
|
||||
|
||||
// Get implements cache.Cache.
|
||||
func (c *Cache[K, V]) Get(key K) (V, bool) {
|
||||
raw, exists := c.store.Load(key)
|
||||
if !exists {
|
||||
return *new(V), false
|
||||
}
|
||||
|
||||
return raw.(V), exists
|
||||
}
|
||||
|
||||
// Set implements cache.Cache.
|
||||
func (c *Cache[K, V]) Set(key K, value V) {
|
||||
c.store.Store(key, value)
|
||||
}
|
||||
|
||||
func NewCache[K comparable, V any]() *Cache[K, V] {
|
||||
return &Cache[K, V]{
|
||||
store: new(sync.Map),
|
||||
}
|
||||
}
|
||||
|
||||
var _ cache.Cache[string, bool] = &Cache[string, bool]{}
|
39
internal/cache/ttl/cache.go
vendored
Normal file
39
internal/cache/ttl/cache.go
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
package ttl
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
cache "forge.cadoles.com/cadoles/bouncer/internal/cache"
|
||||
)
|
||||
|
||||
type Cache[K comparable, V any] struct {
|
||||
timestamps cache.Cache[K, time.Time]
|
||||
values cache.Cache[K, V]
|
||||
ttl time.Duration
|
||||
}
|
||||
|
||||
// Get implements cache.Cache.
|
||||
func (c *Cache[K, V]) Get(key K) (V, bool) {
|
||||
timestamp, exists := c.timestamps.Get(key)
|
||||
if !exists || timestamp.Add(c.ttl).Before(time.Now()) {
|
||||
return *new(V), false
|
||||
}
|
||||
|
||||
return c.values.Get(key)
|
||||
}
|
||||
|
||||
// Set implements cache.Cache.
|
||||
func (c *Cache[K, V]) Set(key K, value V) {
|
||||
c.timestamps.Set(key, time.Now())
|
||||
c.values.Set(key, value)
|
||||
}
|
||||
|
||||
func NewCache[K comparable, V any](values cache.Cache[K, V], timestamps cache.Cache[K, time.Time], ttl time.Duration) *Cache[K, V] {
|
||||
return &Cache[K, V]{
|
||||
values: values,
|
||||
timestamps: timestamps,
|
||||
ttl: ttl,
|
||||
}
|
||||
}
|
||||
|
||||
var _ cache.Cache[string, bool] = &Cache[string, bool]{}
|
39
internal/cache/ttl/cache_test.go
vendored
Normal file
39
internal/cache/ttl/cache_test.go
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
package ttl
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"forge.cadoles.com/cadoles/bouncer/internal/cache/memory"
|
||||
)
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
cache := NewCache(
|
||||
memory.NewCache[string, int](),
|
||||
memory.NewCache[string, time.Time](),
|
||||
time.Second,
|
||||
)
|
||||
|
||||
key := "foo"
|
||||
|
||||
if _, exists := cache.Get(key); exists {
|
||||
t.Errorf("cache.Get(\"%s\"): should not exists", key)
|
||||
}
|
||||
|
||||
cache.Set(key, 1)
|
||||
|
||||
value, exists := cache.Get(key)
|
||||
if !exists {
|
||||
t.Errorf("cache.Get(\"%s\"): should exists", key)
|
||||
}
|
||||
|
||||
if e, g := 1, value; e != g {
|
||||
t.Errorf("cache.Get(\"%s\"): expected '%v', got '%v'", key, e, g)
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
|
||||
if _, exists := cache.Get("foo"); exists {
|
||||
t.Errorf("cache.Get(\"%s\"): should not exists", key)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user