Fixed weird data race

This commit is contained in:
darmiel 2021-04-03 14:00:24 +02:00
parent 1e65f57701
commit ec8e24bd39
7 changed files with 31 additions and 32 deletions

View file

@ -1,4 +1,4 @@
package fcache package bcache
import ( import (
"fmt" "fmt"
@ -17,21 +17,21 @@ func init() {
type node struct { type node struct {
expires nodeExpiration expires nodeExpiration
value interface{} value []byte
} }
type Cache struct { type Cache struct {
mu sync.Mutex mu sync.Mutex
val map[string]*node values map[string]*node
de time.Duration defaultExpiration time.Duration
cleanerInterval time.Duration cleanerInterval time.Duration
} }
func NewCache(defaultExpiration, cleanerInterval time.Duration) *Cache { func NewCache(defaultExpiration, cleanerInterval time.Duration) *Cache {
c := &Cache{ c := &Cache{
val: make(map[string]*node), values: make(map[string]*node),
de: defaultExpiration, defaultExpiration: defaultExpiration,
cleanerInterval: cleanerInterval, cleanerInterval: cleanerInterval,
} }
if cleanerInterval != 0 { if cleanerInterval != 0 {
go c.janitorService() go c.janitorService()
@ -39,30 +39,32 @@ func NewCache(defaultExpiration, cleanerInterval time.Duration) *Cache {
return c return c
} }
func (c *Cache) Set(key string, value interface{}, expiration time.Duration) { func (c *Cache) Set(key string, value []byte, expiration time.Duration) {
c.mu.Lock() c.mu.Lock()
// TODO: remove debug // TODO: remove debug
fmt.Println(prefix, fmt.Println(prefix,
termenv.String("<-").Foreground(common.Profile().Color("#DBAB79")),
"Set", "Set",
termenv.String(key).Foreground(common.Profile().Color("#A8CC8C")), termenv.String(key).Foreground(common.Profile().Color("#A8CC8C")),
termenv.String("=").Foreground(common.Profile().Color("#DBAB79")), termenv.String("=").Foreground(common.Profile().Color("#DBAB79")),
value) value)
c.val[key] = &node{ c.values[key] = &node{
expires: c.expiration(expiration), expires: c.expiration(expiration),
value: value, value: value,
} }
c.mu.Unlock() c.mu.Unlock()
} }
func (c *Cache) Get(key string) (interface{}, bool) { func (c *Cache) Get(key string) ([]byte, bool) {
c.mu.Lock() c.mu.Lock()
if v, o := c.val[key]; o && v != nil { if v, o := c.values[key]; o && v != nil {
if !v.expires.IsExpired() { if !v.expires.IsExpired() {
// TODO: remove debug // TODO: remove debug
fmt.Println(prefix, fmt.Println(prefix,
termenv.String("->").Foreground(common.Profile().Color("#66C2CD")),
"Get", "Get",
termenv.String(key).Foreground(common.Profile().Color("#A8CC8C")), termenv.String(key).Foreground(common.Profile().Color("#A8CC8C")),
termenv.String("=").Foreground(common.Profile().Color("#DBAB79")), termenv.String("=").Foreground(common.Profile().Color("#DBAB79")),

View file

@ -1,4 +1,4 @@
package fcache package bcache
import "time" import "time"
@ -21,7 +21,7 @@ func (c *Cache) expiration(d time.Duration) nodeExpiration {
return 0 return 0
} }
if d == ExpirationDefault { if d == ExpirationDefault {
d = c.de d = c.defaultExpiration
} }
return nodeExpiration(time.Now().Add(d).Unix()) return nodeExpiration(time.Now().Add(d).Unix())
} }

View file

@ -1,4 +1,4 @@
package fcache package bcache
import ( import (
"fmt" "fmt"
@ -22,13 +22,13 @@ func (c *Cache) janitorService() {
func (c *Cache) janitor() { func (c *Cache) janitor() {
c.mu.Lock() c.mu.Lock()
for k, v := range c.val { for k, v := range c.values {
// nil node // nil node
if v == nil || v.expires.IsExpired() { if v == nil || v.expires.IsExpired() {
fmt.Println(prefix, fmt.Println(prefix,
termenv.String("JANITOR").Foreground(common.Profile().Color("#A8CC8C")), termenv.String("JANITOR").Foreground(common.Profile().Color("#A8CC8C")),
"Deleting", termenv.String(k).Foreground(common.Profile().Color("#A8CC8C"))) "Deleting", termenv.String(k).Foreground(common.Profile().Color("#A8CC8C")))
delete(c.val, k) delete(c.values, k)
} }
} }
c.mu.Unlock() c.mu.Unlock()

View file

@ -1,12 +1,12 @@
package server package server
import ( import (
"github.com/darmiel/yaxc/internal/fcache" "github.com/darmiel/yaxc/internal/bcache"
"time" "time"
) )
type CacheBackend struct { type CacheBackend struct {
cache *fcache.Cache cache *bcache.Cache
errCast error errCast error
} }
@ -19,21 +19,18 @@ func (b *CacheBackend) GetHash(key string) (res string, err error) {
} }
func (b *CacheBackend) Set(key, value string, ttl time.Duration) error { func (b *CacheBackend) Set(key, value string, ttl time.Duration) error {
b.cache.Set("val::"+key, value, ttl) b.cache.Set("val::"+key, []byte(value), ttl)
return nil return nil
} }
func (b *CacheBackend) SetHash(key, value string, ttl time.Duration) error { func (b *CacheBackend) SetHash(key, value string, ttl time.Duration) error {
b.cache.Set("hash::"+key, value, ttl) b.cache.Set("hash::"+key, []byte(value), ttl)
return nil return nil
} }
func (b *CacheBackend) get(key string) (res string, err error) { func (b *CacheBackend) get(key string) (res string, err error) {
if v, ok := b.cache.Get(key); ok { if v, ok := b.cache.Get(key); ok {
if s, ok := v.(string); ok { res = string(v)
return s, nil
}
return "", b.errCast
} }
return "", nil return
} }

View file

@ -30,7 +30,7 @@ func (s *yAxCServer) handleGetAnywhere(ctx *fiber.Ctx) (err error) {
} }
} }
log.Warning(ctx.IP(), "requested VALUE", path) // log.Warning(ctx.IP(), "requested VALUE", path)
if res == "" { if res == "" {
ctx.Status(404) ctx.Status(404)
@ -47,7 +47,7 @@ func (s *yAxCServer) handleGetHashAnywhere(ctx *fiber.Ctx) (err error) {
return return
} }
log.Warning(ctx.IP(), "requested HASH", path, "with result", res, "::", res[:4]) // log.Warning(ctx.IP(), "requested HASH", path, "with result", res, "::", res[:4])
if res == "" { if res == "" {
ctx.Status(404) ctx.Status(404)

View file

@ -81,7 +81,7 @@ func (s *yAxCServer) setAnywhereWithHash(ctx *fiber.Ctx, path, hash string) (err
fmt.Sprintf("ERROR (Val): %v\nERROR (Hsh): %v", errVal, errHsh)) fmt.Sprintf("ERROR (Val): %v\nERROR (Hsh): %v", errVal, errHsh))
} }
log.Debug(ctx.IP(), "updated", path, "with hash", hash) //log.Debug(ctx.IP(), "updated", path, "with hash", hash)
return ctx.Status(200).SendString(content) return ctx.Status(200).SendString(content)
} }

View file

@ -3,7 +3,7 @@ package server
import ( import (
"context" "context"
"errors" "errors"
"github.com/darmiel/yaxc/internal/fcache" "github.com/darmiel/yaxc/internal/bcache"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/op/go-logging" "github.com/op/go-logging"
@ -60,7 +60,7 @@ func NewServer(cfg *YAxCConfig) (s *yAxCServer) {
if s.RedisAddress == "" { if s.RedisAddress == "" {
// use cache backend // use cache backend
s.Backend = &CacheBackend{ s.Backend = &CacheBackend{
cache: fcache.NewCache(s.DefaultTTL, 10*time.Second), cache: bcache.NewCache(s.DefaultTTL, 10*time.Second),
errCast: errors.New("not a string"), errCast: errors.New("not a string"),
} }
} else { } else {