mirror of
https://github.com/darmiel/yaxc.git
synced 2024-09-20 14:56:14 +08:00
Fixed weird data race
This commit is contained in:
parent
1e65f57701
commit
ec8e24bd39
|
@ -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")),
|
|
@ -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())
|
||||||
}
|
}
|
|
@ -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()
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue