chore: improve template gen (#192)

* chore: improve repo template gen
* chore: import cache template gen
* chore: import protoc-gen-go-gin template gen
* feat: add sonic json encoding

* docs: add feature

Co-authored-by: lvjiapeng <319161@myj.com.cn>
This commit is contained in:
vv06161
2025-07-19 09:30:48 +08:00
committed by GitHub
parent 5882db2acc
commit 1e0d1f1c4f
9 changed files with 113 additions and 57 deletions

View File

@@ -1,7 +1,8 @@
module github.com/go-eagle/eagle/cmd/eagle
go 1.22
toolchain go1.24.1
go 1.23.0
toolchain go1.24.3
require (
github.com/AlecAivazis/survey/v2 v2.2.12

View File

@@ -48,10 +48,10 @@ type {{.LcName}}Cache struct {
// New{{.Name}}Cache new a cache
func New{{.Name}}Cache(rdb *redis.Client) {{.Name}}Cache {
jsonEncoding := encoding.JSONEncoding{}
sonicEncoding := encoding.SonicEncoding{}
cachePrefix := ""
return &{{.LcName}}Cache{
cache: cache.NewRedisCache(rdb, cachePrefix, jsonEncoding, func() interface{} {
cache: cache.NewRedisCache(rdb, cachePrefix, sonicEncoding, func() interface{} {
return &model.{{.Name}}Model{}
}),
}

View File

@@ -16,6 +16,7 @@ import (
"time"
localCache "github.com/go-eagle/eagle/pkg/cache"
cacheBase "github.com/go-eagle/eagle/pkg/cache"
"github.com/go-eagle/eagle/pkg/encoding"
"github.com/pkg/errors"
"github.com/spf13/cast"
@@ -57,7 +58,7 @@ func New{{.Name}}Repo(db *dal.DBClient, cache cache.{{.Name}}Cache) {{.Name}}Rep
db: db,
tracer: otel.Tracer("{{.LcName}}"),
cache: cache,
localCache: localCache.NewMemoryCache("local:{{.LcName}}:", encoding.JSONEncoding{}),
localCache: localCache.NewMemoryCache("local:{{.LcName}}:", encoding.SonicEncoding{}),
sg: singleflight.Group{},
}
}
@@ -124,13 +125,9 @@ func (r *{{.LcName}}Repo) Get{{.Name}}(ctx context.Context, id int64) (ret *mode
// read redis cache
ret, err = r.cache.Get{{.Name}}Cache(ctx, id)
if err != nil {
return nil, err
}
if ret != nil && ret.ID > 0 {
return ret, nil
}
if errors.Is(err, cacheBase.ErrPlaceholder) {
return nil, gorm.ErrRecordNotFound
} else if errors.Is(err, redis.ErrRedisNotFound) {
// get data from db
// 避免缓存击穿(瞬间有大量请求过来)
val, err, _ := r.sg.Do("sg:{{.LcName}}:"+cast.ToString(id), func() (interface{}, error) {
@@ -166,6 +163,11 @@ func (r *{{.LcName}}Repo) Get{{.Name}}(ctx context.Context, id int64) (ret *mode
}
return val.(*model.{{.Name}}Model), nil
} else if err != nil {
return nil, err
}
return ret, nil
{{- else }}
// read db
ret, err = dao.{{.Name}}Model.WithContext(ctx).Where(dao.{{.Name}}Model.ID.Eq(id)).Last()

View File

@@ -18,6 +18,7 @@ const (
metadataPackage = protogen.GoImportPath("google.golang.org/grpc/metadata")
eagleAppPackage = protogen.GoImportPath("github.com/go-eagle/eagle/pkg/app")
errCodePackage = protogen.GoImportPath("github.com/go-eagle/eagle/pkg/errcode")
utilsPackage = protogen.GoImportPath("github.com/go-eagle/eagle/pkg/utils")
deprecationComment = "// Deprecated: Do not use."
)
@@ -40,7 +41,7 @@ func generateFile(gen *protogen.Plugin, file *protogen.File) *protogen.Generated
g.P()
g.P("// ", contextPackage.Ident(""))
g.P("// ", metadataPackage.Ident(""))
g.P("// ", ginPackage.Ident(""), eagleAppPackage.Ident(""), errCodePackage.Ident(""))
g.P("// ", ginPackage.Ident(""), eagleAppPackage.Ident(""), errCodePackage.Ident(""), utilsPackage.Ident(""))
g.P()
for _, service := range file.Services {

View File

@@ -31,14 +31,19 @@ type {{$.Name}} struct{
{{range .Methods}}
func (s *{{$.Name}}) {{ .HandlerName }} (ctx *gin.Context) {
var in {{.Request}}
var err error
{{if eq .Method "GET" }}
if err := ctx.ShouldBindQuery(&in); err != nil {
if err = ctx.ShouldBindQuery(&in); err != nil {
app.Error(ctx, errcode.ErrInvalidParam.WithDetails(err.Error()))
return
}
{{if .HasPathParams }}
// make sure the uri include :id
in.Id = ctx.Param("id")
in.Id, err = utils.StringToInt64((ctx.Param("id")))
if err != nil {
app.Error(ctx, errcode.ErrInvalidParam.WithDetails(err.Error()))
return
}
{{end}}
{{else if eq .Method "POST" "PUT" "PATCH" "DELETE"}}
if err := ctx.ShouldBindJSON(&in); err != nil {
@@ -47,7 +52,11 @@ func (s *{{$.Name}}) {{ .HandlerName }} (ctx *gin.Context) {
}
{{if .HasPathParams }}
// make sure the uri include :id
in.Id = ctx.Param("id")
in.Id, err = utils.StringToInt64((ctx.Param("id")))
if err != nil {
app.Error(ctx, errcode.ErrInvalidParam.WithDetails(err.Error()))
return
}
{{end}}
{{else}}
if err := ctx.ShouldBind(&in); err != nil {

View File

@@ -78,7 +78,8 @@ func main() {
}
// init service
service.Svc = service.New(repository.New(model.GetDB()))
db, _ := model.GetDB()
service.Svc = service.New(repository.New(db))
gin.SetMode(cfg.Mode)

View File

@@ -10,9 +10,9 @@ import (
)
func getCacheClient(ctx context.Context) cache.Cache {
jsonEncoding := encoding.JSONEncoding{}
sonicEncoding := encoding.SonicEncoding{}
cachePrefix := ""
client := cache.NewRedisCache(redis.RedisClient, cachePrefix, jsonEncoding, func() interface{} {
client := cache.NewRedisCache(redis.RedisClient, cachePrefix, sonicEncoding, func() interface{} {
return &model.UserBaseModel{}
})

View File

@@ -0,0 +1,45 @@
package encoding
import (
"github.com/bytedance/sonic"
"github.com/golang/snappy"
)
type SonicEncoding struct {
}
func (s SonicEncoding) Marshal(v interface{}) ([]byte, error) {
buf, err := sonic.Marshal(v)
return buf, err
}
func (s SonicEncoding) Unmarshal(data []byte, value interface{}) error {
err := sonic.Unmarshal(data, value)
if err != nil {
return err
}
return nil
}
// SonicSnappyEncoding Sonic json格式和snappy压缩
type SonicSnappyEncoding struct{}
// Marshal 序列化
func (s SonicSnappyEncoding) Marshal(v interface{}) (data []byte, err error) {
b, err := sonic.Marshal(v)
if err != nil {
return nil, err
}
d := snappy.Encode(nil, b)
return d, nil
}
// Unmarshal 反序列化
func (s SonicSnappyEncoding) Unmarshal(data []byte, value interface{}) error {
b, err := snappy.Decode(nil, data)
if err != nil {
return err
}
return sonic.Unmarshal(b, value)
}

View File

@@ -6,7 +6,7 @@ import (
"strings"
"unsafe"
jsoniter "github.com/json-iterator/go"
"github.com/bytedance/sonic"
)
// IsEmpty 是否是空字符串
@@ -97,12 +97,9 @@ func StringToBytes(s string) []byte {
return *(*[]byte)(unsafe.Pointer(&h))
}
// 对于序列化和反序列化场景较多的服务可以使用性能更高的json-iterator
// https://github.com/json-iterator/go
var Json = jsoniter.Config{
var Json = sonic.Config{
EscapeHTML: true,
SortMapKeys: true,
ValidateJsonRawMessage: true,
UseNumber: true,
}.Froze()