feat(cache): add timestamp

This commit is contained in:
Jan De Dobbeleer 2021-09-22 07:53:59 +02:00 committed by Jan De Dobbeleer
parent 7d2001c936
commit 7738cad7cb
3 changed files with 64 additions and 23 deletions

View file

@ -3,24 +3,24 @@ package main
import "sync"
type concurrentMap struct {
values map[string]string
values map[string]interface{}
lock sync.RWMutex
}
func newConcurrentMap() *concurrentMap {
return &concurrentMap{
values: make(map[string]string),
values: make(map[string]interface{}),
lock: sync.RWMutex{},
}
}
func (c *concurrentMap) set(key, value string) {
func (c *concurrentMap) set(key string, value interface{}) {
c.lock.Lock()
defer c.lock.Unlock()
c.values[key] = value
}
func (c *concurrentMap) get(key string) (string, bool) {
func (c *concurrentMap) get(key string) (interface{}, bool) {
c.lock.RLock()
defer c.lock.RUnlock()
if val, ok := c.values[key]; ok {
@ -28,3 +28,13 @@ func (c *concurrentMap) get(key string) (string, bool) {
}
return "", false
}
func (c *concurrentMap) remove(key string) {
c.lock.RLock()
defer c.lock.RUnlock()
delete(c.values, key)
}
func (c *concurrentMap) list() map[string]interface{} {
return c.values
}

View file

@ -52,7 +52,8 @@ type cache interface {
init(home string)
close()
get(key string) (string, bool)
set(key, value string)
// ttl in seconds
set(key, value string, ttl int64)
}
type environmentInfo interface {
@ -97,7 +98,14 @@ func (c *commandCache) set(command, path string) {
}
func (c *commandCache) get(command string) (string, bool) {
return c.commands.get(command)
cmd, found := c.commands.get(command)
if !found {
return "", false
}
if command, ok := cmd.(string); ok {
return command, true
}
return "", false
}
type tracer struct {

View file

@ -1,15 +1,21 @@
package main
import (
"fmt"
"encoding/json"
"io/ioutil"
"strings"
"time"
)
const (
cachePath = "/.omp.cache"
)
type cacheObject struct {
Value string `json:"value"`
Timestamp int64 `json:"timestamp"`
TTL int64 `json:"ttl"`
}
type fileCache struct {
cache *concurrentMap
home string
@ -18,32 +24,49 @@ type fileCache struct {
func (fc *fileCache) init(home string) {
fc.cache = newConcurrentMap()
fc.home = home
content, err := ioutil.ReadFile(home + cachePath)
content, err := ioutil.ReadFile(fc.home + cachePath)
if err != nil {
return
}
for _, line := range strings.Split(string(content), "\n") {
if len(line) == 0 || !strings.Contains(line, "=") {
continue
}
kv := strings.SplitN(line, "=", 2)
fc.set(kv[0], kv[1])
var list map[string]*cacheObject
if err := json.Unmarshal(content, &list); err != nil {
return
}
for key, co := range list {
fc.cache.set(key, co)
}
}
func (fc *fileCache) close() {
var sb strings.Builder
for key, value := range fc.cache.values {
cacheEntry := fmt.Sprintf("%s=%s\n", key, value)
sb.WriteString(cacheEntry)
fc.set("hello", "world", 200)
if dump, err := json.Marshal(fc.cache.list()); err == nil {
_ = ioutil.WriteFile(fc.home+cachePath, dump, 0644)
}
_ = ioutil.WriteFile(fc.home+cachePath, []byte(sb.String()), 0644)
}
func (fc *fileCache) get(key string) (string, bool) {
return fc.cache.get(key)
val, found := fc.cache.get(key)
if !found {
return "", false
}
co, ok := val.(*cacheObject)
if !ok {
return "", false
}
expired := time.Now().Unix() >= (co.Timestamp + co.TTL*60)
if expired {
fc.cache.remove(key)
return "", false
}
return co.Value, true
}
func (fc *fileCache) set(key, value string) {
fc.cache.set(key, value)
func (fc *fileCache) set(key, value string, ttl int64) {
fc.cache.set(key, &cacheObject{
Value: value,
Timestamp: time.Now().Unix(),
TTL: ttl,
})
}