avoid bigint converted into float64 when unmarshaling
This commit is contained in:
10
core/stores/cache/cachenode.go
vendored
10
core/stores/cache/cachenode.go
vendored
@@ -1,13 +1,13 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/tal-tech/go-zero/core/jsonx"
|
||||||
"github.com/tal-tech/go-zero/core/logx"
|
"github.com/tal-tech/go-zero/core/logx"
|
||||||
"github.com/tal-tech/go-zero/core/mathx"
|
"github.com/tal-tech/go-zero/core/mathx"
|
||||||
"github.com/tal-tech/go-zero/core/stat"
|
"github.com/tal-tech/go-zero/core/stat"
|
||||||
@@ -79,7 +79,7 @@ func (c cacheNode) SetCache(key string, v interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c cacheNode) SetCacheWithExpire(key string, v interface{}, expire time.Duration) error {
|
func (c cacheNode) SetCacheWithExpire(key string, v interface{}, expire time.Duration) error {
|
||||||
data, err := json.Marshal(v)
|
data, err := jsonx.Marshal(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ func (c cacheNode) doTake(v interface{}, key string, query func(v interface{}) e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return json.Marshal(v)
|
return jsonx.Marshal(v)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -181,11 +181,11 @@ func (c cacheNode) doTake(v interface{}, key string, query func(v interface{}) e
|
|||||||
c.stat.IncrementHit()
|
c.stat.IncrementHit()
|
||||||
}
|
}
|
||||||
|
|
||||||
return json.Unmarshal(val.([]byte), v)
|
return jsonx.Unmarshal(val.([]byte), v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c cacheNode) processCache(key string, data string, v interface{}) error {
|
func (c cacheNode) processCache(key string, data string, v interface{}) error {
|
||||||
err := json.Unmarshal([]byte(data), v)
|
err := jsonx.Unmarshal([]byte(data), v)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
30
core/stores/cache/cachenode_test.go
vendored
30
core/stores/cache/cachenode_test.go
vendored
@@ -2,7 +2,9 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -176,3 +178,31 @@ func TestCacheNode_String(t *testing.T) {
|
|||||||
}
|
}
|
||||||
assert.Equal(t, s.Addr(), cn.String())
|
assert.Equal(t, s.Addr(), cn.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCacheValueWithBigInt(t *testing.T) {
|
||||||
|
s, err := miniredis.Run()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
cn := cacheNode{
|
||||||
|
rds: redis.NewRedis(s.Addr(), redis.NodeType),
|
||||||
|
r: rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||||
|
barrier: syncx.NewSharedCalls(),
|
||||||
|
lock: new(sync.Mutex),
|
||||||
|
unstableExpiry: mathx.NewUnstable(expiryDeviation),
|
||||||
|
stat: NewCacheStat("any"),
|
||||||
|
errNotFound: errors.New("any"),
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
key = "key"
|
||||||
|
value int64 = 323427211229009810
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.Nil(t, cn.SetCache(key, value))
|
||||||
|
var val interface{}
|
||||||
|
assert.Nil(t, cn.GetCache(key, &val))
|
||||||
|
assert.Equal(t, strconv.FormatInt(value, 10), fmt.Sprintf("%v", val))
|
||||||
|
}
|
||||||
|
|||||||
@@ -83,10 +83,6 @@ func (cc CachedConn) QueryRowIndex(v interface{}, key string, keyer func(primary
|
|||||||
var primaryKey interface{}
|
var primaryKey interface{}
|
||||||
var found bool
|
var found bool
|
||||||
|
|
||||||
// if don't use convert numeric primary key into int64,
|
|
||||||
// then it will be represented as scientific notion, like 2e6
|
|
||||||
// which will make the cache doesn't match with the previous insert one
|
|
||||||
keyer = floatKeyer(keyer)
|
|
||||||
if err := cc.cache.TakeWithExpire(&primaryKey, key, func(val interface{}, expire time.Duration) (err error) {
|
if err := cc.cache.TakeWithExpire(&primaryKey, key, func(val interface{}, expire time.Duration) (err error) {
|
||||||
primaryKey, err = indexQuery(cc.db, v)
|
primaryKey, err = indexQuery(cc.db, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -124,16 +120,3 @@ func (cc CachedConn) SetCache(key string, v interface{}) error {
|
|||||||
func (cc CachedConn) Transact(fn func(sqlx.Session) error) error {
|
func (cc CachedConn) Transact(fn func(sqlx.Session) error) error {
|
||||||
return cc.db.Transact(fn)
|
return cc.db.Transact(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func floatKeyer(fn func(interface{}) string) func(interface{}) string {
|
|
||||||
return func(primary interface{}) string {
|
|
||||||
switch v := primary.(type) {
|
|
||||||
case float32:
|
|
||||||
return fn(int64(v))
|
|
||||||
case float64:
|
|
||||||
return fn(int64(v))
|
|
||||||
default:
|
|
||||||
return fn(primary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -594,20 +594,6 @@ func TestQueryRowNoCache(t *testing.T) {
|
|||||||
assert.True(t, ran)
|
assert.True(t, ran)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatKeyer(t *testing.T) {
|
|
||||||
primaries := []interface{}{
|
|
||||||
float32(1),
|
|
||||||
float64(1),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, primary := range primaries {
|
|
||||||
val := floatKeyer(func(i interface{}) string {
|
|
||||||
return fmt.Sprint(i)
|
|
||||||
})(primary)
|
|
||||||
assert.Equal(t, "1", val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resetStats() {
|
func resetStats() {
|
||||||
atomic.StoreUint64(&stats.Total, 0)
|
atomic.StoreUint64(&stats.Total, 0)
|
||||||
atomic.StoreUint64(&stats.Hit, 0)
|
atomic.StoreUint64(&stats.Hit, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user