Skip to content
This repository has been archived by the owner on Apr 20, 2023. It is now read-only.

Commit

Permalink
Detach asynchronous request from current context
Browse files Browse the repository at this point in the history
  • Loading branch information
paulo-raca committed Apr 20, 2023
1 parent 03526f4 commit 6bbd60b
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions httpcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package httpcache
import (
"bufio"
"bytes"
"context"
"errors"
"io"
"io/ioutil"
Expand Down Expand Up @@ -108,6 +109,8 @@ type Transport struct {
Cache Cache
// If true, responses returned from the cache will be given an extra header, X-From-Cache
MarkCachedResponses bool
// Context timeout for async requests triggered by stale-while-revalidate
AsyncRevalidateTimeout time.Duration
}

// NewTransport returns a new Transport with the
Expand Down Expand Up @@ -172,11 +175,18 @@ func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error
if freshness == fresh {
return cachedResp, nil
} else if freshness == staleWhileRevalidate {
noCacheRequest := *req
noCacheRequest.Header = noCacheRequest.Header.Clone()
bgContext := context.Background()
var cancelContext context.CancelFunc = nil
if t.AsyncRevalidateTimeout > 0 {
bgContext, cancelContext = context.WithTimeout(bgContext, t.AsyncRevalidateTimeout)
}
noCacheRequest := req.Clone(bgContext)
noCacheRequest.Header.Set("cache-control", "no-cache")
go func() {
resp, err := t.RoundTrip(&noCacheRequest)
if cancelContext != nil {
defer cancelContext()
}
resp, err := t.RoundTrip(noCacheRequest)
if err == nil {
defer resp.Body.Close()
buffer := make([]byte, 4096)
Expand Down

0 comments on commit 6bbd60b

Please sign in to comment.