Skip to content

Commit 811cf1b

Browse files
Use flightCache for HEAD request caching
Instead of handrolling a cache for the HEAD requests to determine etags, this reuses the flightCache to deal with caching HEAD responses, if desired.
1 parent 4586db5 commit 811cf1b

File tree

1 file changed

+12
-32
lines changed

1 file changed

+12
-32
lines changed

pkg/apk/apk/cache.go

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ func (f *flightCache[T]) Do(key string, fn func() (T, error)) (T, error) {
8787
}
8888

8989
type Cache struct {
90-
etagCache *sync.Map
9190
headFlight *singleflight.Group
9291
getFlight *singleflight.Group
9392

9493
discoverKeys *flightCache[[]Key]
94+
etags *flightCache[*http.Response]
9595
}
9696

9797
// NewCache returns a new Cache, which allows us to persist the results of HEAD requests
@@ -113,33 +113,13 @@ func NewCache(etag bool) *Cache {
113113
}
114114

115115
if etag {
116-
c.etagCache = &sync.Map{}
116+
//nolint:bodyclose // Body is already closed before caching.
117+
c.etags = newFlightCache[*http.Response]()
117118
}
118119

119120
return c
120121
}
121122

122-
func (c *Cache) load(cacheFile string) (*http.Response, bool) {
123-
if c == nil || c.etagCache == nil {
124-
return nil, false
125-
}
126-
127-
v, ok := c.etagCache.Load(cacheFile)
128-
if !ok {
129-
return nil, false
130-
}
131-
132-
return v.(*http.Response), true
133-
}
134-
135-
func (c *Cache) store(cacheFile string, resp *http.Response) {
136-
if c == nil || c.etagCache == nil {
137-
return
138-
}
139-
140-
c.etagCache.Store(cacheFile, resp)
141-
}
142-
143123
// cache
144124
type cache struct {
145125
dir string
@@ -209,12 +189,7 @@ func (t *cacheTransport) RoundTrip(request *http.Request) (*http.Response, error
209189
}
210190

211191
func (t *cacheTransport) head(request *http.Request, cacheFile string) (*http.Response, error) {
212-
resp, ok := t.cache.load(cacheFile)
213-
if ok {
214-
return resp, nil
215-
}
216-
217-
v, err, _ := t.cache.headFlight.Do(cacheFile, func() (any, error) {
192+
fetch := func() (*http.Response, error) {
218193
req := request.Clone(request.Context())
219194
req.Method = http.MethodHead
220195
resp, err := t.wrapped.Do(req)
@@ -225,14 +200,19 @@ func (t *cacheTransport) head(request *http.Request, cacheFile string) (*http.Re
225200
// HEAD shouldn't have a body. Make sure we close it so we can reuse the connection.
226201
defer resp.Body.Close()
227202

228-
t.cache.store(cacheFile, resp)
229-
230203
return resp, nil
204+
}
205+
206+
v, err, _ := t.cache.headFlight.Do(cacheFile, func() (any, error) {
207+
if t.cache.etags != nil {
208+
return t.cache.etags.Do(cacheFile, fetch)
209+
}
210+
//nolint:bodyclose // Body is already closed in fetch.
211+
return fetch()
231212
})
232213
if err != nil {
233214
return nil, err
234215
}
235-
236216
return v.(*http.Response), nil
237217
}
238218

0 commit comments

Comments
 (0)