Skip to content

Commit eca3d49

Browse files
committed
feat: add BeforeReplyWithCacheCallback option (#7)
1 parent 4c3babe commit eca3d49

2 files changed

Lines changed: 37 additions & 14 deletions

File tree

cache.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@ func Cache(
3333
defaultExpire time.Duration,
3434
opts ...Option,
3535
) gin.HandlerFunc {
36-
cfg := &Config{
37-
logger: Discard{},
38-
hitCacheCallback: defaultHitCacheCallback,
39-
shareSingleFlightCallback: defaultShareSingleFlightCallback,
40-
}
36+
cfg := newConfig()
4137

4238
for _, opt := range opts {
4339
opt(cfg)
@@ -67,7 +63,7 @@ func Cache(
6763

6864
// read cache first
6965
{
70-
respCache := &responseCache{}
66+
respCache := &ResponseCache{}
7167
err := cacheStore.Get(cacheKey, &respCache)
7268
if err == nil {
7369
replyWithCache(c, cfg, respCache)
@@ -99,7 +95,7 @@ func Cache(
9995

10096
inFlight = true
10197

102-
respCache := &responseCache{}
98+
respCache := &ResponseCache{}
10399
respCache.fillWithCacheWriter(cacheWriter)
104100

105101
// only cache 2xx response
@@ -113,7 +109,7 @@ func Cache(
113109
})
114110

115111
if !inFlight {
116-
replyWithCache(c, cfg, rawRespCache.(*responseCache))
112+
replyWithCache(c, cfg, rawRespCache.(*ResponseCache))
117113
cfg.shareSingleFlightCallback(c)
118114
}
119115
}
@@ -141,16 +137,17 @@ func CacheByRequestPath(defaultCacheStore persist.CacheStore, defaultExpire time
141137
}
142138

143139
func init() {
144-
gob.Register(&responseCache{})
140+
gob.Register(&ResponseCache{})
145141
}
146142

147-
type responseCache struct {
143+
// ResponseCache record the http response cache
144+
type ResponseCache struct {
148145
Status int
149146
Header http.Header
150147
Data []byte
151148
}
152149

153-
func (c *responseCache) fillWithCacheWriter(cacheWriter *responseCacheWriter) {
150+
func (c *ResponseCache) fillWithCacheWriter(cacheWriter *responseCacheWriter) {
154151
c.Status = cacheWriter.Status()
155152
c.Data = cacheWriter.body.Bytes()
156153
c.Header = cacheWriter.Header().Clone()
@@ -175,8 +172,10 @@ func (w *responseCacheWriter) WriteString(s string) (int, error) {
175172
func replyWithCache(
176173
c *gin.Context,
177174
cfg *Config,
178-
respCache *responseCache,
175+
respCache *ResponseCache,
179176
) {
177+
cfg.beforeReplyWithCacheCallback(c, respCache)
178+
180179
c.Writer.WriteHeader(respCache.Status)
181180

182181
for key, values := range respCache.Header {

option.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,21 @@ type Config struct {
1414

1515
hitCacheCallback OnHitCacheCallback
1616

17+
beforeReplyWithCacheCallback BeforeReplyWithCacheCallback
18+
1719
singleFlightForgetTimeout time.Duration
1820
shareSingleFlightCallback OnShareSingleFlightCallback
1921
}
2022

23+
func newConfig() *Config {
24+
return &Config{
25+
logger: Discard{},
26+
hitCacheCallback: defaultHitCacheCallback,
27+
beforeReplyWithCacheCallback: defaultBeforeReplyWithCacheCallback,
28+
shareSingleFlightCallback: defaultShareSingleFlightCallback,
29+
}
30+
}
31+
2132
// Option represents the optional function.
2233
type Option func(c *Config)
2334

@@ -67,6 +78,19 @@ func WithOnHitCache(cb OnHitCacheCallback) Option {
6778
}
6879
}
6980

81+
type BeforeReplyWithCacheCallback func(c *gin.Context, cache *ResponseCache)
82+
83+
var defaultBeforeReplyWithCacheCallback = func(c *gin.Context, cache *ResponseCache) {}
84+
85+
// WithBeforeReplyWithCache will be called before replying with cache.
86+
func WithBeforeReplyWithCache(cb BeforeReplyWithCacheCallback) Option {
87+
return func(c *Config) {
88+
if cb != nil {
89+
c.beforeReplyWithCacheCallback = cb
90+
}
91+
}
92+
}
93+
7094
// OnShareSingleFlightCallback define the callback when share the singleflight result
7195
type OnShareSingleFlightCallback func(c *gin.Context)
7296

@@ -81,8 +105,8 @@ func WithOnShareSingleFlight(cb OnShareSingleFlightCallback) Option {
81105
}
82106
}
83107

84-
// WithSingleFlightForgetTimeout to reduce the impact of long tail requests. when request in the singleflight,
85-
// after the forget timeout, singleflight.Forget will be called
108+
// WithSingleFlightForgetTimeout to reduce the impact of long tail requests.
109+
// singleflight.Forget will be called after the timeout has reached for each backend request when timeout is greater than zero.
86110
func WithSingleFlightForgetTimeout(forgetTimeout time.Duration) Option {
87111
return func(c *Config) {
88112
if forgetTimeout > 0 {

0 commit comments

Comments
 (0)