no caching is used by default

This commit is contained in:
zhuyasen 2023-12-15 22:04:06 +08:00
parent d391c735fa
commit e346cc27de
16 changed files with 106 additions and 45 deletions

6
.github/RELEASE.md vendored
View File

@ -1,5 +1,5 @@
## Change log
- Fix bug with naocs as service discovery.
- Add support for distributed transaction manager [DTM](https://github.com/dtm-labs/dtm).
- Add a list api interface for GET methods.
- Adjust the code.
- Support copying the specified proto file to the grpc service.
- The default is not to use the cache, according to the need to choose to use redis or memory as a cache.

View File

@ -189,7 +189,7 @@ update-config:
.PHONY: clean
# clean binary file, cover.out, template file
clean:
@rm -vrf cmd/serverNameExample_mixExample/serverNameExample_mixExample
@rm -vrf cmd/serverNameExample_mixExample/serverNameExample_mixExample*
@rm -vrf cover.out
@rm -vrf main.go serverNameExample_mixExample.gv
@rm -vrf internal/ecode/*.go.gen*

View File

@ -128,7 +128,7 @@ update-config:
.PHONY: clean
# clean binary file, cover.out, template file
clean:
@rm -vrf cmd/serverNameExample_mixExample/serverNameExample_mixExample
@rm -vrf cmd/serverNameExample_mixExample/serverNameExample_mixExample*
@rm -vrf cover.out
@rm -vrf main.go serverNameExample_mixExample.gv
@rm -vrf internal/ecode/*.go.gen*

View File

@ -6,13 +6,13 @@ package initial
import (
"flag"
"fmt"
"github.com/zhufuyi/sponge/pkg/conf"
"strconv"
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/internal/model"
"github.com/zhufuyi/sponge/pkg/conf"
"github.com/zhufuyi/sponge/pkg/logger"
"github.com/zhufuyi/sponge/pkg/nacoscli"
"github.com/zhufuyi/sponge/pkg/stat"

View File

@ -14,7 +14,7 @@ app:
enableTrace: false # whether to turn on trace, true:enable, false:disable, if true jaeger configuration must be set
tracingSamplingRate: 1.0 # tracing sampling rate, between 0 and 1, 0 means no sampling, 1 means sampling all links
registryDiscoveryType: "" # registry and discovery types: consul, etcd, nacos, if empty, registration and discovery are not used
cacheType: "memory" # cache type, "memory" or "redis", if set to redis, must set redis configuration
cacheType: "" # cache type, if empty, the cache is not used, Support for "memory" and "redis", if set to redis, must set redis configuration
# todo generate http or rpc server configuration here

View File

@ -1,4 +1,5 @@
# Generate the go struct command: sponge config --server-dir=./serverDir
# App config from nacos
# nacos settings
nacos:

2
go.mod
View File

@ -7,7 +7,7 @@ require (
github.com/alicebob/miniredis/v2 v2.23.0
github.com/blastrain/vitess-sqlparser v0.0.0-20201030050434-a139afbb1aba
github.com/bojand/ghz v0.110.0
github.com/dgraph-io/ristretto v0.1.0
github.com/dgraph-io/ristretto v0.1.1
github.com/felixge/fgprof v0.9.3
github.com/fsnotify/fsnotify v1.5.4
github.com/gin-contrib/cors v1.3.1

5
go.sum
View File

@ -138,8 +138,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI=
github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug=
github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
@ -925,6 +925,7 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=

View File

@ -22,7 +22,7 @@ const (
// cache prefix key, must end with a colon
cacheNameExampleCachePrefixKey = "prefixKeyExample:"
// CacheNameExampleExpireTime expire time
CacheNameExampleExpireTime = 10 * time.Minute
CacheNameExampleExpireTime = 5 * time.Minute
)
var _ CacheNameExampleCache = (*cacheNameExampleCache)(nil)
@ -46,16 +46,17 @@ func NewCacheNameExampleCache(cacheType *model.CacheType) CacheNameExampleCache
cachePrefix := ""
jsonEncoding := encoding.JSONEncoding{}
var c cache.Cache
if strings.ToLower(cacheType.CType) == "redis" {
c = cache.NewRedisCache(cacheType.Rdb, cachePrefix, jsonEncoding, newObject)
} else {
c = cache.NewMemoryCache(cachePrefix, jsonEncoding, newObject)
cType := strings.ToLower(cacheType.CType)
switch cType {
case "redis":
c := cache.NewRedisCache(cacheType.Rdb, cachePrefix, jsonEncoding, newObject)
return &cacheNameExampleCache{cache: c}
case "memory":
c := cache.NewMemoryCache(cachePrefix, jsonEncoding, newObject)
return &cacheNameExampleCache{cache: c}
}
return &cacheNameExampleCache{
cache: c,
}
panic(fmt.Sprintf("unsupported cache type='%s'", cacheType.CType))
}
// cache key

View File

@ -21,8 +21,8 @@ type cacheNameExampleData struct {
func newCacheNameExampleCache() *gotest.Cache {
// change the type of the value before testing
var (
key keyTypeExample = "foo1"
val valueTypeExample = "bar1"
key = "foo1"
val = "bar1"
)
record1 := &cacheNameExampleData{ID: 1, Key: key, Value: val}
@ -82,3 +82,17 @@ func Test_cacheNameExampleCache_Del(t *testing.T) {
t.Fatal(err)
}
}
func TestNewCacheNameExampleCache(t *testing.T) {
c := NewCacheNameExampleCache(&model.CacheType{
CType: "memory",
})
assert.NotNil(t, c)
defer func() {
_ = recover()
}()
c = NewCacheNameExampleCache(&model.CacheType{
CType: "",
})
}

View File

@ -16,7 +16,7 @@ const (
// cache prefix key, must end with a colon
userExampleCachePrefixKey = "userExample:"
// UserExampleExpireTime expire time
UserExampleExpireTime = 10 * time.Minute
UserExampleExpireTime = 5 * time.Minute
)
var _ UserExampleCache = (*userExampleCache)(nil)
@ -40,20 +40,22 @@ type userExampleCache struct {
func NewUserExampleCache(cacheType *model.CacheType) UserExampleCache {
jsonEncoding := encoding.JSONEncoding{}
cachePrefix := ""
var c cache.Cache
if strings.ToLower(cacheType.CType) == "redis" {
c = cache.NewRedisCache(cacheType.Rdb, cachePrefix, jsonEncoding, func() interface{} {
cType := strings.ToLower(cacheType.CType)
switch cType {
case "redis":
c := cache.NewRedisCache(cacheType.Rdb, cachePrefix, jsonEncoding, func() interface{} {
return &model.UserExample{}
})
} else {
c = cache.NewMemoryCache(cachePrefix, jsonEncoding, func() interface{} {
return &userExampleCache{cache: c}
case "memory":
c := cache.NewMemoryCache(cachePrefix, jsonEncoding, func() interface{} {
return &model.UserExample{}
})
return &userExampleCache{cache: c}
}
return &userExampleCache{
cache: c,
}
return nil // no cache
}
// GetUserExampleCacheKey cache key

View File

@ -130,8 +130,15 @@ func Test_userExampleCache_SetCacheWithNotFound(t *testing.T) {
func TestNewUserExampleCache(t *testing.T) {
c := NewUserExampleCache(&model.CacheType{
CType: "",
})
assert.Nil(t, c)
c = NewUserExampleCache(&model.CacheType{
CType: "memory",
})
assert.NotNil(t, c)
c = NewUserExampleCache(&model.CacheType{
CType: "redis",
})
assert.NotNil(t, c)
}

View File

@ -38,12 +38,15 @@ type UserExampleDao interface {
type userExampleDao struct {
db *gorm.DB
cache cache.UserExampleCache
sfg *singleflight.Group
cache cache.UserExampleCache // if nil, the cache is not used.
sfg *singleflight.Group // if cache is nil, the sfg is not used.
}
// NewUserExampleDao creating the dao interface
func NewUserExampleDao(db *gorm.DB, xCache cache.UserExampleCache) UserExampleDao {
if xCache == nil {
return &userExampleDao{db: db}
}
return &userExampleDao{
db: db,
cache: xCache,
@ -51,10 +54,17 @@ func NewUserExampleDao(db *gorm.DB, xCache cache.UserExampleCache) UserExampleDa
}
}
func (d *userExampleDao) deleteCache(ctx context.Context, id uint64) error {
if d.cache != nil {
return d.cache.Del(ctx, id)
}
return nil
}
// Create a record, insert the record and the id value is written back to the table
func (d *userExampleDao) Create(ctx context.Context, table *model.UserExample) error {
err := d.db.WithContext(ctx).Create(table).Error
_ = d.cache.Del(ctx, table.ID)
_ = d.deleteCache(ctx, table.ID)
return err
}
@ -66,7 +76,7 @@ func (d *userExampleDao) DeleteByID(ctx context.Context, id uint64) error {
}
// delete cache
_ = d.cache.Del(ctx, id)
_ = d.deleteCache(ctx, id)
return nil
}
@ -80,7 +90,7 @@ func (d *userExampleDao) DeleteByIDs(ctx context.Context, ids []uint64) error {
// delete cache
for _, id := range ids {
_ = d.cache.Del(ctx, id)
_ = d.deleteCache(ctx, id)
}
return nil
@ -91,7 +101,7 @@ func (d *userExampleDao) UpdateByID(ctx context.Context, table *model.UserExampl
err := d.updateDataByID(ctx, d.db, table)
// delete cache
_ = d.cache.Del(ctx, table.ID)
_ = d.deleteCache(ctx, table.ID)
return err
}
@ -135,6 +145,14 @@ func (d *userExampleDao) updateDataByID(ctx context.Context, db *gorm.DB, table
// GetByID get a record by id
func (d *userExampleDao) GetByID(ctx context.Context, id uint64) (*model.UserExample, error) {
// no cache
if d.cache == nil {
record := &model.UserExample{}
err := d.db.WithContext(ctx).Where("id = ?", id).First(record).Error
return record, err
}
// get from cache or mysql
record, err := d.cache.Get(ctx, id)
if err == nil {
return record, nil
@ -217,6 +235,21 @@ func (d *userExampleDao) GetByCondition(ctx context.Context, c *query.Conditions
// GetByIDs get records by batch id
func (d *userExampleDao) GetByIDs(ctx context.Context, ids []uint64) (map[uint64]*model.UserExample, error) {
// no cache
if d.cache == nil {
var records []*model.UserExample
err := d.db.WithContext(ctx).Where("id IN (?)", ids).Find(&records).Error
if err != nil {
return nil, err
}
itemMap := make(map[uint64]*model.UserExample)
for _, record := range records {
itemMap[record.ID] = record
}
return itemMap, nil
}
// get form cache or mysql
itemMap, err := d.cache.MultiGet(ctx, ids)
if err != nil {
return nil, err
@ -358,7 +391,7 @@ func (d *userExampleDao) DeleteByTx(ctx context.Context, tx *gorm.DB, id uint64)
}
// delete cache
_ = d.cache.Del(ctx, id)
_ = d.deleteCache(ctx, id)
return nil
}
@ -368,7 +401,7 @@ func (d *userExampleDao) UpdateByTx(ctx context.Context, tx *gorm.DB, table *mod
err := d.updateDataByID(ctx, tx, table)
// delete cache
_ = d.cache.Del(ctx, table.ID)
_ = d.deleteCache(ctx, table.ID)
return err
}

View File

@ -1,3 +1,4 @@
// Package client is generic grpc client-side.
package client
import (
@ -45,9 +46,9 @@ func WithLoadBalance() Option {
}
// WithSecure set secure
func WithSecure(credentials credentials.TransportCredentials) Option {
func WithSecure(credential credentials.TransportCredentials) Option {
return func(o *options) {
o.credentials = credentials
o.credentials = credential
}
}

View File

@ -1,3 +1,4 @@
// Package server is generic grpc server-side.
package server
import (
@ -36,9 +37,9 @@ func (o *options) apply(opts ...Option) {
}
// WithSecure set secure
func WithSecure(credentials credentials.TransportCredentials) Option {
func WithSecure(credential credentials.TransportCredentials) Option {
return func(o *options) {
o.credentials = credentials
o.credentials = credential
}
}

View File

@ -121,8 +121,8 @@ func GetConfig(params *Params, opts ...Option) (string, []byte, error) {
// Init get configuration from nacos and parse to struct, use for configuration center
//
// Deprecated: use GetConfig instead.
func Init(obj interface{}, params *Params, opts ...Option) error {
return errors.New("not implemented")
func Init(_ interface{}, _ *Params, _ ...Option) error {
return errors.New("not implemented, use GetConfig instead")
}
// NewNamingClient create a service registration and discovery of nacos client.