当前仓库属于暂停状态,部分功能使用受限,详情请查阅 仓库状态说明
55 Star 269 Fork 100

fagongzi/gateway
暂停

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
filter_caching.go 2.47 KB
一键复制 编辑 原始数据 按行查看 历史
package proxy
import (
"strings"
"sync"
"time"
"github.com/fagongzi/gateway/pkg/filter"
"github.com/fagongzi/gateway/pkg/pb/metapb"
"github.com/fagongzi/gateway/pkg/util"
"github.com/fagongzi/goetty"
"github.com/fagongzi/util/hack"
"github.com/valyala/fasthttp"
)
var (
cachePool sync.Pool
)
// CachingFilter cache api result
type CachingFilter struct {
filter.BaseFilter
tw *goetty.TimeoutWheel
cache *util.Cache
}
func newCachingFilter(maxBytes uint64, tw *goetty.TimeoutWheel) filter.Filter {
return &CachingFilter{
tw: tw,
cache: util.NewLRUCache(maxBytes),
}
}
// Name return name of this filter
func (f *CachingFilter) Name() string {
return FilterCaching
}
// Pre execute before proxy
func (f *CachingFilter) Pre(c filter.Context) (statusCode int, err error) {
if c.DispatchNode().Cache == nil {
return f.BaseFilter.Post(c)
}
matches, id := getCachingID(c)
if !matches {
return f.BaseFilter.Post(c)
}
if value, ok := f.cache.Get(id); ok {
c.SetAttr(filter.UsingCachingValue, value)
}
return f.BaseFilter.Post(c)
}
// Post execute after proxy
func (f *CachingFilter) Post(c filter.Context) (statusCode int, err error) {
if c.DispatchNode().Cache == nil {
return f.BaseFilter.Post(c)
}
matches, id := getCachingID(c)
if !matches {
return f.BaseFilter.Post(c)
}
f.cache.Add(id, genCachedValue(c))
f.tw.Schedule(time.Second*time.Duration(c.DispatchNode().Cache.Deadline),
f.removeCache, id)
return f.BaseFilter.Post(c)
}
func (f *CachingFilter) removeCache(id interface{}) {
f.cache.Remove(id)
}
func getCachingID(c filter.Context) (bool, string) {
req := c.ForwardRequest()
if len(c.DispatchNode().Cache.Conditions) == 0 {
return true, getID(req, c.DispatchNode().Cache.Keys)
}
matches := true
for _, cond := range c.DispatchNode().Cache.Conditions {
matches = conditionsMatches(&cond, req)
if !matches {
break
}
}
if !matches {
return false, ""
}
return matches, getID(req, c.DispatchNode().Cache.Keys)
}
func getID(req *fasthttp.Request, keys []metapb.Parameter) string {
size := len(keys)
if size == 0 {
return hack.SliceToString(req.RequestURI())
}
ids := make([]string, size+1, size+1)
ids[0] = hack.SliceToString(req.RequestURI())
for idx, param := range keys {
ids[idx+1] = paramValue(&param, req)
}
return strings.Join(ids, "-")
}
func genCachedValue(c filter.Context) []byte {
contentType := c.Response().Header.ContentType()
body := c.Response().Body()
return filter.NewCachedValue(body, contentType)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/fagongzi/gateway.git
git@gitee.com:fagongzi/gateway.git
fagongzi
gateway
gateway
v2.1.1

搜索帮助