@@ -40,7 +40,8 @@ type microcache struct {
40
40
collapseMutex * sync.Mutex
41
41
42
42
// Used to advance time for testing
43
- offset time.Duration
43
+ offset time.Duration
44
+ offsetMutex * sync.RWMutex
44
45
}
45
46
46
47
type Config struct {
@@ -155,6 +156,7 @@ func New(o Config) *microcache {
155
156
revalidateMutex : & sync.Mutex {},
156
157
collapse : map [string ]* sync.Mutex {},
157
158
collapseMutex : & sync.Mutex {},
159
+ offsetMutex : & sync.RWMutex {},
158
160
}
159
161
if o .Driver == nil {
160
162
m .Driver = NewDriverLRU (1e4 ) // default 10k cache items
@@ -180,6 +182,9 @@ func New(o Config) *microcache {
180
182
// chain.Append(mx.Middleware)
181
183
//
182
184
func (m * microcache ) Middleware (h http.Handler ) http.Handler {
185
+ if m .Timeout > 0 {
186
+ h = http .TimeoutHandler (h , m .Timeout , "Timed out" )
187
+ }
183
188
return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
184
189
// Websocket passthrough
185
190
upgrade := strings .ToLower (r .Header .Get ("connection" )) == "upgrade"
@@ -259,7 +264,7 @@ func (m *microcache) Middleware(h http.Handler) http.Handler {
259
264
}
260
265
261
266
// Fresh response object found
262
- if obj .found && obj .expires .After (time . Now (). Add ( m . offset )) {
267
+ if obj .found && obj .expires .After (m . now ( )) {
263
268
if m .Monitor != nil {
264
269
m .Monitor .Hit ()
265
270
}
@@ -273,7 +278,7 @@ func (m *microcache) Middleware(h http.Handler) http.Handler {
273
278
274
279
// Stale While Revalidate
275
280
if obj .found && req .staleWhileRevalidate > 0 &&
276
- obj .expires .Add (req .staleWhileRevalidate ).After (time . Now (). Add ( m . offset )) {
281
+ obj .expires .Add (req .staleWhileRevalidate ).After (m . now ( )) {
277
282
if m .Monitor != nil {
278
283
m .Monitor .Stale ()
279
284
}
@@ -291,15 +296,15 @@ func (m *microcache) Middleware(h http.Handler) http.Handler {
291
296
}
292
297
m .revalidateMutex .Unlock ()
293
298
if ! revalidating {
299
+ br := newBackgroundRequest (r )
294
300
go func () {
295
301
defer func () {
296
302
// Clear revalidation lock
297
303
m .revalidateMutex .Lock ()
298
304
delete (m .revalidating , objHash )
299
305
m .revalidateMutex .Unlock ()
300
306
}()
301
-
302
- m .handleBackendResponse (h , w , r , reqHash , req , objHash , obj , true )
307
+ m .handleBackendResponse (h , w , br , reqHash , req , objHash , obj , true )
303
308
}()
304
309
}
305
310
@@ -329,12 +334,7 @@ func (m *microcache) handleBackendResponse(
329
334
beres := Response {header : http.Header {}}
330
335
331
336
// Execute request
332
- if m .Timeout > 0 {
333
- th := http .TimeoutHandler (h , m .Timeout , "Timed out" )
334
- th .ServeHTTP (& beres , r )
335
- } else {
336
- h .ServeHTTP (& beres , r )
337
- }
337
+ h .ServeHTTP (& beres , r )
338
338
339
339
if ! beres .headerWritten {
340
340
beres .status = http .StatusOK
@@ -347,10 +347,10 @@ func (m *microcache) handleBackendResponse(
347
347
348
348
// Serve Stale
349
349
if beres .status >= 500 && obj .found {
350
- serveStale := obj .expires .Add (req .staleIfError ).After (time . Now (). Add ( m . offset ))
350
+ serveStale := obj .expires .Add (req .staleIfError ).After (m . now ( ))
351
351
// Extend stale response expiration by staleIfError grace period
352
352
if req .found && serveStale && req .staleRecache {
353
- obj .expires = obj .date .Add (m .offset ).Add (req .ttl )
353
+ obj .expires = obj .date .Add (m .getOffset () ).Add (req .ttl )
354
354
m .store (objHash , obj )
355
355
}
356
356
if ! background && serveStale {
@@ -376,7 +376,7 @@ func (m *microcache) handleBackendResponse(
376
376
}
377
377
// Cache response
378
378
if ! req .nocache {
379
- beres .expires = time . Now (). Add ( m . offset ).Add (req .ttl )
379
+ beres .expires = m . now ( ).Add (req .ttl )
380
380
m .store (objHash , beres )
381
381
}
382
382
}
@@ -418,7 +418,7 @@ func (m *microcache) Start() {
418
418
// setAgeHeader sets the age header if not suppressed
419
419
func (m * microcache ) setAgeHeader (w http.ResponseWriter , obj Response ) {
420
420
if ! m .SuppressAgeHeader {
421
- age := (time . Now (). Add ( m . offset ).Unix () - obj .date .Unix ())
421
+ age := (m . now ( ).Unix () - obj .date .Unix ())
422
422
w .Header ().Set ("age" , fmt .Sprintf ("%d" , age ))
423
423
}
424
424
}
@@ -444,5 +444,19 @@ func (m *microcache) Stop() {
444
444
445
445
// Increments the offset for testing purposes
446
446
func (m * microcache ) offsetIncr (o time.Duration ) {
447
+ m .offsetMutex .Lock ()
448
+ defer m .offsetMutex .Unlock ()
447
449
m .offset += o
448
450
}
451
+
452
+ // Get offset
453
+ func (m * microcache ) getOffset () time.Duration {
454
+ m .offsetMutex .RLock ()
455
+ defer m .offsetMutex .RUnlock ()
456
+ return m .offset
457
+ }
458
+
459
+ // Get current time with offset
460
+ func (m * microcache ) now () time.Time {
461
+ return time .Now ().Add (m .getOffset ())
462
+ }
0 commit comments