github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/znet/cache/cache.go (about) 1 package cache 2 3 import ( 4 "sort" 5 "time" 6 7 "github.com/sohaha/zlsgo/zcache" 8 "github.com/sohaha/zlsgo/znet" 9 "github.com/sohaha/zlsgo/zstring" 10 ) 11 12 type ( 13 // Config configuration 14 Config struct { 15 Custom func(c *znet.Context) (key string, expiration time.Duration) 16 zcache.Options 17 } 18 cacheContext struct { 19 Type string 20 Content []byte 21 Code int32 22 } 23 ) 24 25 func New(opt ...func(conf *Config)) znet.HandlerFunc { 26 conf := Config{ 27 Custom: func(c *znet.Context) (key string, expiration time.Duration) { 28 return QueryKey(c), 0 29 }, 30 } 31 32 cache := zcache.NewFast(func(o *zcache.Options) { 33 conf.Options = *o 34 conf.Options.Expiration = time.Minute * 10 35 for _, f := range opt { 36 f(&conf) 37 } 38 *o = conf.Options 39 }) 40 41 return func(c *znet.Context) { 42 key, expiration := conf.Custom(c) 43 if key == "" { 44 c.Next() 45 return 46 } 47 48 v, ok := cache.ProvideGet(key, func() (interface{}, bool) { 49 c.Next() 50 51 p := c.PrevContent() 52 if p.Code.Load() != 0 { 53 return &cacheContext{ 54 Code: p.Code.Load(), 55 Type: p.Type, 56 Content: p.Content, 57 }, true 58 } 59 return nil, false 60 }, expiration) 61 62 if !ok { 63 return 64 } 65 66 if data, ok := v.(*cacheContext); ok { 67 p := c.PrevContent() 68 p.Code.Store(data.Code) 69 p.Content = data.Content 70 p.Type = data.Type 71 c.Abort() 72 } 73 } 74 } 75 76 func QueryKey(c *znet.Context) (key string) { 77 m := c.GetAllQueryMaps() 78 mLen := len(m) 79 if mLen == 0 { 80 return c.Request.URL.Path 81 } 82 83 keys := make([]string, 0, mLen) 84 for k := range m { 85 keys = append(keys, k) 86 } 87 sort.Strings(keys) 88 89 b := zstring.Buffer((len(m) * 4) + 2) 90 b.WriteString(c.Request.URL.Path) 91 b.WriteString("?") 92 for _, k := range keys { 93 b.WriteString(k) 94 b.WriteString("=") 95 b.WriteString(m[k]) 96 b.WriteString("&") 97 } 98 return b.String() 99 }