update genmc

pull/410/head
小旭 5 years ago
parent 4d4fc4e345
commit f7c596cff5
  1. 5
      tool/kratos-gen-mc/README.md
  2. 4
      tool/kratos-gen-mc/header_template.go
  3. 62
      tool/kratos-gen-mc/main.go
  4. 5
      tool/kratos-gen-mc/multi_template.go
  5. 5
      tool/kratos-gen-mc/none_template.go
  6. 5
      tool/kratos-gen-mc/single_template.go

@ -40,5 +40,6 @@ mc Add方法需要用注解 -type=only_add单独指定
| batch | | get(限多key模板) | 批量获取数据 每组大小 | - | 100 |
| max_group | | get(限多key模板) | 批量获取数据 最大组数量 | - | 10 |
| batch_err | break | get(限多key模板) | 批量获取数据回源错误的时候 降级继续请求(continue)还是直接返回(break) | break 或 continue | continue |
| struct_name | Dao | 全部 | 用户自定义Dao结构体名称 | | MemcacheDao |
| struct_name | dao | 全部 | 用户自定义Dao结构体名称 | | MemcacheDao |
|check_null_code||add/set|(和null_expire配套使用)判断是否是空缓存的代码 用于为空缓存独立设定过期时间||$.ID==-1 或者 $=="-1"等|
|null_expire|300(5分钟)|add/set|(和check_null_code配套使用)空缓存的过期时间||d.nullExpire|

@ -25,7 +25,5 @@ NEWLINE
{{.ImportPackage}}
)
var (
_ _mc
)
var _ _mc
`

@ -9,26 +9,29 @@ import (
"os"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"text/template"
"github.com/bilibili/kratos/tool/pkg"
common "github.com/bilibili/kratos/tool/pkg"
)
var (
encode = flag.String("encode", "", "encode type: json/pb/raw/gob/gzip")
mcType = flag.String("type", "", "type: get/set/del/replace/only_add")
key = flag.String("key", "", "key name method")
expire = flag.String("expire", "", "expire time code")
structName = flag.String("struct_name", "Dao", "struct name")
batchSize = flag.Int("batch", 0, "batch size")
batchErr = flag.String("batch_err", "break", "batch err to contine or break")
maxGroup = flag.Int("max_group", 0, "max group size")
encode = flag.String("encode", "", "encode type: json/pb/raw/gob/gzip")
mcType = flag.String("type", "", "type: get/set/del/replace/only_add")
key = flag.String("key", "", "key name method")
expire = flag.String("expire", "", "expire time code")
structName = flag.String("struct_name", "dao", "struct name")
batchSize = flag.Int("batch", 0, "batch size")
batchErr = flag.String("batch_err", "break", "batch err to contine or break")
maxGroup = flag.Int("max_group", 0, "max group size")
checkNullCode = flag.String("check_null_code", "", "check null code")
nullExpire = flag.String("null_expire", "", "null cache expire time code")
mcValidTypes = []string{"set", "replace", "del", "get", "only_add"}
mcValidPrefix = []string{"set", "replace", "del", "get", "cache", "add"}
optionNamesMap = map[string]bool{"batch": true, "max_group": true, "encode": true, "type": true, "key": true, "expire": true, "batch_err": true, "struct_name": true}
optionNamesMap = map[string]bool{"batch": true, "max_group": true, "encode": true, "type": true, "key": true, "expire": true, "batch_err": true, "struct_name": true, "check_null_code": true, "null_expire": true}
simpleTypes = []string{"int", "int8", "int16", "int32", "int64", "float32", "float64", "uint", "uint8", "uint16", "uint32", "uint64", "bool", "string", "[]byte"}
lenTypes = []string{"[]", "map"}
)
@ -51,6 +54,9 @@ func resetFlag() {
*batchSize = 0
*maxGroup = 0
*batchErr = "break"
*checkNullCode = ""
*nullExpire = ""
*structName = "dao"
}
// options options
@ -88,17 +94,20 @@ type options struct {
LenType bool
PointType bool
StructName string
CheckNullCode string
ExpireNullCode string
EnableNullCode bool
}
func getOptions(opt *options, comment string) {
os.Args = []string{os.Args[0]}
if regexp.MustCompile(`\s+//\s*mc:.+`).Match([]byte(comment)) {
args := strings.Split(pkg.RegexpReplace(`//\s*mc:(?P<arg>.+)`, comment, "$arg"), " ")
args := strings.Split(common.RegexpReplace(`//\s*mc:(?P<arg>.+)`, comment, "$arg"), " ")
for _, arg := range args {
arg = strings.TrimSpace(arg)
if arg != "" {
// validate option name
argName := pkg.RegexpReplace(`-(?P<name>[\w_-]+)=.+`, arg, "$name")
argName := common.RegexpReplace(`-(?P<name>[\w_-]+)=.+`, arg, "$name")
if !optionNamesMap[argName] {
log.Fatalf("选项:%s 不存在 请检查拼写\n", argName)
}
@ -122,9 +131,16 @@ func getOptions(opt *options, comment string) {
opt.GroupSize = *batchSize
opt.MaxGroup = *maxGroup
opt.StructName = *structName
opt.CheckNullCode = *checkNullCode
if *nullExpire != "" {
opt.ExpireNullCode = *nullExpire
}
if opt.CheckNullCode != "" {
opt.EnableNullCode = true
}
}
func getTypeFromPrefix(opt *options, params []*ast.Field, s *pkg.Source) {
func getTypeFromPrefix(opt *options, params []*ast.Field, s *common.Source) {
if opt.MCType == "" {
for _, t := range mcValidPrefix {
if strings.HasPrefix(strings.ToLower(opt.name), t) {
@ -160,7 +176,7 @@ func getTypeFromPrefix(opt *options, params []*ast.Field, s *pkg.Source) {
}
}
func processList(s *pkg.Source, list *ast.Field) (opt options) {
func processList(s *common.Source, list *ast.Field) (opt options) {
src := s.Src
fset := s.Fset
lines := strings.Split(src, "\n")
@ -168,11 +184,12 @@ func processList(s *pkg.Source, list *ast.Field) (opt options) {
opt.name = list.Names[0].Name
opt.KeyMethod = "key" + opt.name
opt.ExpireCode = "d.mc" + opt.name + "Expire"
opt.ExpireNullCode = "300" // 默认5分钟
// get comment
line := fset.Position(list.Pos()).Line - 3
if len(lines)-1 >= line {
comment := lines[line]
opt.Comment = pkg.RegexpReplace(`\s+//(?P<name>.+)`, comment, "$name")
opt.Comment = common.RegexpReplace(`\s+//(?P<name>.+)`, comment, "$name")
opt.Comment = strings.TrimSpace(opt.Comment)
}
// get options
@ -235,7 +252,7 @@ func processList(s *pkg.Source, list *ast.Field) (opt options) {
return
}
func getKeyValueType(opt *options, params, results []*ast.Field, s *pkg.Source) {
func getKeyValueType(opt *options, params, results []*ast.Field, s *common.Source) {
// check
if s.ExprString(results[len(results)-1].Type) != "error" {
log.Fatalln("最后返回值参数需为error")
@ -352,7 +369,7 @@ func getKeyValueType(opt *options, params, results []*ast.Field, s *pkg.Source)
}
}
func parse(s *pkg.Source) (opts []*options) {
func parse(s *common.Source) (opts []*options) {
c := s.F.Scope.Lookup(_interfaceName)
if (c == nil) || (c.Kind != ast.Typ) {
log.Fatalln("无法找到缓存声明")
@ -476,6 +493,9 @@ func genBody(opts []*options) (res string) {
src = strings.Replace(src, "VALUE", option.ValueType, -1)
src = strings.Replace(src, "GROUPSIZE", strconv.Itoa(option.GroupSize), -1)
src = strings.Replace(src, "MAXGROUP", strconv.Itoa(option.MaxGroup), -1)
if option.EnableNullCode {
option.CheckNullCode = strings.Replace(option.CheckNullCode, "$", "val", -1)
}
t := template.Must(template.New("cache").Parse(src))
var buffer bytes.Buffer
err := t.Execute(&buffer, option)
@ -494,13 +514,15 @@ func main() {
log.SetFlags(0)
defer func() {
if err := recover(); err != nil {
log.Fatalf("程序解析失败, err: %+v", err)
buf := make([]byte, 64*1024)
buf = buf[:runtime.Stack(buf, false)]
log.Fatalf("程序解析失败, err: %+v stack: %s 请企业微信联系 @wangxu01", err, buf)
}
}()
options := parse(pkg.NewSource(pkg.SourceText()))
options := parse(common.NewSource(common.SourceText()))
header := genHeader(options)
body := genBody(options)
code := pkg.FormatCode(header + "\n" + body)
code := common.FormatCode(header + "\n" + body)
// Write to file.
dir := filepath.Dir(".")
outputName := filepath.Join(dir, "mc.cache.go")

@ -167,6 +167,11 @@ func (d *{{.StructName}}) NAME(c context.Context, values map[KEY]VALUE {{.ExtraA
{{else}}
item := &memcache.Item{Key: key, Object: val, Expiration: {{.ExpireCode}}, Flags: {{.Encode}}}
{{end}}
{{if .EnableNullCode}}
if {{.CheckNullCode}} {
item.Expiration = {{.ExpireNullCode}}
}
{{end}}
if err = d.mc.Set(c, item); err != nil {
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return

@ -72,6 +72,11 @@ func (d *{{.StructName}}) NAME(c context.Context, val VALUE) (err error) {
{{else}}
item := &memcache.Item{Key: key, Object: val, Expiration: {{.ExpireCode}}, Flags: {{.Encode}}}
{{end}}
{{if .EnableNullCode}}
if {{.CheckNullCode}} {
item.Expiration = {{.ExpireNullCode}}
}
{{end}}
if err = d.mc.Set(c, item); err != nil {
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return

@ -71,6 +71,11 @@ func (d *{{.StructName}}) NAME(c context.Context, id KEY, val VALUE {{.ExtraArgs
{{else}}
item := &memcache.Item{Key: key, Object: val, Expiration: {{.ExpireCode}}, Flags: {{.Encode}}}
{{end}}
{{if .EnableNullCode}}
if {{.CheckNullCode}} {
item.Expiration = {{.ExpireNullCode}}
}
{{end}}
if err = d.mc.Set(c, item); err != nil {
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return

Loading…
Cancel
Save