-
Notifications
You must be signed in to change notification settings - Fork 25
Open
Description
场景:
使用redis缓存用户的请求结果,return c.JSON(http.StatusOK, commom.SuccessPayload(data))
做法:
在router 层面使用 redis 缓存的handlerFunc, 伪代码
r.GET("/redis", commom.CacheBefore(), db2.RedisTest, commom.CacheAfter())
解释:
根据用户的请求参数,请求uri, 做md5计算得到 key
CacheBefore(), 判断是否有key 缓存,有则返回, 无则注入request param, redis_cache=key
CacheAfter(),将db2.RedisTest 返回的Response 结果 存入redis
修改:
源码中 Context.go ->Next() 方法不使用if c.w.Written(){ break } 方法中断, 因为 hanlders 中可能有多个json 返回,这样会提前结束。
- Next() 方法增加一个标志位 if c.w.Break() {break} 。
- response_overide.go:
a. ResponseWriter 增加 Break() , 用于判断是否要在 Next()中随时返回
b. responseWriter 增加 body *bytes.Buffer ; breakNext bool 两个参数,breakNext用于 c.w.Break() , body用于拦截前面hander返回的json 数据,写入redis.
补充:
func CacheBefore() yee.HandlerFunc {
return func(c yee.Context) (err error) {
urI := c.RequestURI()
if (strings.Contains(urI, "/api/v2/redis") || strings.Contains(urI, "/api/v2/fetch/idc") || strings.Contains(urI, "/api/v2/fetch/")) && c.Request().Method == http.MethodGet {
// 角色
_, role := lib.JwtParse(c)
// 请求参数
cacheKey := StringToMd5(urI + role)
if val, err := lib.HasKey(cacheKey); err == nil {
fmt.Printf("return CacheBefore value , cacheKey: %s", cacheKey)
return c.JSON(http.StatusOK, val, true)
} else {
return c.JSON(http.StatusInternalServerError, err.Error(), true)
}
// 标记将结果缓存到 redis, key=yea_cache , value=cacheKey
c.InjectQueryParam(model.RedisKey, cacheKey)
fmt.Printf("CacheBefore need redis cacheKey: %s\n", cacheKey)
}
return
}
}
func CacheAfter() yee.HandlerFunc {
return func(c yee.Context) (err error) {
header := c.Response().Header().Get(yee.HeaderContentType)
cacheKey := c.QueryParam(model.RedisKey)
if cacheKey != "" && header == yee.MIMEApplicationJSONCharsetUTF8 {
body := c.Response().Body()
fmt.Printf("CacheAfter write data into redis : %+v \n", body)
err = model.RDB().Set(context.Background(), cacheKey, body, model.DefaultCacheTime).Err()
if err != nil {
fmt.Printf("could not set data in Redis: %v \n", err)
return c.JSON(http.StatusOK, ERR_COMMON_MESSAGE(err))
}
fmt.Println("RedisTest Data stored in Redis OK !")
}
return
}
}
// context.go
func (c *context) JSON(code int, i interface{}, args ...interface{}) (err error) {
if !c.writermem.Written() {
enc := json.NewEncoder(c.w)
c.writeContentType(MIMEApplicationJSONCharsetUTF8)
c.w.WriteHeader(code)
if len(args) > 0 {
if flag, ok := args[0].(bool); ok {
c.Response().InjectBreak(flag)
}
}
return enc.Encode(i)
}
return
}
以上
Metadata
Metadata
Assignees
Labels
No labels