openreplay/backend/pkg/cache/cache.go
Alexander 481db19dbe
Go redshift connector (#1457)
* feat(backend): redshift connector draft

* fix(backend): fixed memory leak, empty string ddos

* feat(backend): draft for sessions part

* feat(backend): session handler

* fix(backend): fixed wrong columns list in sessionToCSV convertor

* feat(backend): load session info from db/cache if there is nothing in memory when sessionEnd event recieved

* feat(backend): added filters for connector

* feat(backend): memory leak fix + extra cache for sessions

* feat(backend): moved table names as an env variable

* fix(backend): added timeout for last session messages to avoid memory leak

* fix(backend): fixed last memory leak

* feat(backend): moved redshift connector to ee folder
2023-09-05 12:18:47 +02:00

82 lines
1.6 KiB
Go

package cache
import (
"sync"
"time"
)
type Cache interface {
Set(key, value interface{})
Get(key interface{}) (interface{}, bool)
GetAndRefresh(key interface{}) (interface{}, bool)
SetCache(sessID uint64, data map[string]string) error
GetCache(sessID uint64) (map[string]string, error)
}
type item struct {
data interface{}
lastUsage time.Time
}
type cacheImpl struct {
mutex sync.Mutex
items map[interface{}]item
}
func (c *cacheImpl) SetCache(sessID uint64, data map[string]string) error {
return nil
}
func (c *cacheImpl) GetCache(sessID uint64) (map[string]string, error) {
return nil, nil
}
func New(cleaningInterval, itemDuration time.Duration) Cache {
cache := &cacheImpl{items: make(map[interface{}]item)}
go func() {
cleanTick := time.Tick(cleaningInterval)
for {
select {
case <-cleanTick:
cache.mutex.Lock()
now := time.Now()
for k, v := range cache.items {
if now.Sub(v.lastUsage) > itemDuration {
delete(cache.items, k)
}
}
cache.mutex.Unlock()
}
}
}()
return cache
}
func (c *cacheImpl) Set(key, value interface{}) {
c.mutex.Lock()
defer c.mutex.Unlock()
c.items[key] = item{
data: value,
lastUsage: time.Now(),
}
}
func (c *cacheImpl) Get(key interface{}) (interface{}, bool) {
c.mutex.Lock()
defer c.mutex.Unlock()
if v, ok := c.items[key]; ok {
return v.data, ok
}
return nil, false
}
func (c *cacheImpl) GetAndRefresh(key interface{}) (interface{}, bool) {
c.mutex.Lock()
defer c.mutex.Unlock()
v, ok := c.items[key]
if ok {
v.lastUsage = time.Now()
c.items[key] = v
}
return v.data, ok
}