Skip to content

Commit 9958cc8

Browse files
authored
azureblob: support multiple cache download URLs (#934)
* azureblob: support multiple cache download URLs * len() will always yield 0
1 parent 4f935fa commit 9958cc8

File tree

2 files changed

+78
-19
lines changed

2 files changed

+78
-19
lines changed

internal/agent/http_cache/azureblob/getblob.go

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,46 @@ func (azureBlob *AzureBlob) getBlob(writer http.ResponseWriter, request *http.Re
3434
},
3535
)
3636
if err != nil {
37-
fail(writer, request, http.StatusInternalServerError, "failed to generate cache download URL",
37+
fail(writer, request, http.StatusInternalServerError, "failed to generate cache download URLs",
3838
"key", key, "err", err)
3939

4040
return
4141
}
4242

43-
if len(generateCacheDownloadURLResponse.Urls) != 1 {
43+
if len(generateCacheDownloadURLResponse.Urls) == 0 {
4444
fail(writer, request, http.StatusInternalServerError, fmt.Sprintf("failed to generate"+
45-
" cache download URL: expected 1 URL, got %d", len(generateCacheDownloadURLResponse.Urls)))
45+
" cache download URLs: expected at least 1 URL, got 0"))
4646

4747
return
4848
}
4949

5050
// Proxy cache entry download
51-
req, err := http.NewRequestWithContext(request.Context(), http.MethodGet,
52-
generateCacheDownloadURLResponse.Urls[0], nil)
51+
for i, url := range generateCacheDownloadURLResponse.Urls {
52+
isLastIteration := i == len(generateCacheDownloadURLResponse.Urls)-1
53+
54+
if azureBlob.proxyCacheEntryDownload(writer, request, key, url, isLastIteration) {
55+
break
56+
}
57+
}
58+
}
59+
60+
func (azureBlob *AzureBlob) proxyCacheEntryDownload(
61+
writer http.ResponseWriter,
62+
request *http.Request,
63+
key string,
64+
url string,
65+
isLastIteration bool,
66+
) bool {
67+
req, err := http.NewRequestWithContext(request.Context(), http.MethodGet, url, nil)
5368
if err != nil {
69+
if !isLastIteration {
70+
return false
71+
}
72+
5473
fail(writer, request, http.StatusInternalServerError, "failed to create request to proxy"+
5574
" cache entry download", "key", key, "err", err)
5675

57-
return
76+
return true
5877
}
5978

6079
// Support HTTP range requests
@@ -67,24 +86,37 @@ func (azureBlob *AzureBlob) getBlob(writer http.ResponseWriter, request *http.Re
6786

6887
resp, err := azureBlob.potentiallyCachingHTTPClient.Do(req)
6988
if err != nil {
89+
if !isLastIteration {
90+
return false
91+
}
92+
7093
fail(writer, request, http.StatusInternalServerError, "failed to perform request to proxy"+
7194
" cache entry download", "key", key, "err", err)
7295

73-
return
96+
return true
7497
}
98+
defer resp.Body.Close()
7599

76100
switch resp.StatusCode {
77101
case http.StatusOK, http.StatusPartialContent:
78102
// Proceed with proxying
79103
case http.StatusNotFound:
104+
if !isLastIteration {
105+
return false
106+
}
107+
80108
writer.WriteHeader(http.StatusNotFound)
81109

82-
return
110+
return true
83111
default:
112+
if !isLastIteration {
113+
return false
114+
}
115+
84116
fail(writer, request, http.StatusInternalServerError, fmt.Sprintf("failed to perform request to proxy"+
85117
" cache entry download, got unexpected HTTP %d", resp.StatusCode), "key", key)
86118

87-
return
119+
return true
88120
}
89121

90122
// Chacha doesn't support Range requests yet, and not disclosing Content-Length
@@ -108,9 +140,11 @@ func (azureBlob *AzureBlob) getBlob(writer http.ResponseWriter, request *http.Re
108140
})
109141
bytesRead, err := io.CopyBuffer(writer, progressReader, largeBuffer)
110142
if err != nil {
111-
proxyingDuration := time.Since(startProxyingAt)
112143
fail(writer, request, http.StatusInternalServerError, "failed to proxy cache entry download",
113-
"err", err, "duration", proxyingDuration, "read", bytesRead, "key", key)
114-
return
144+
"err", err, "duration", time.Since(startProxyingAt), "read", bytesRead, "key", key)
145+
146+
return true
115147
}
148+
149+
return true
116150
}

internal/agent/http_cache/azureblob/headblob.go

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,35 +26,58 @@ func (azureBlob *AzureBlob) headBlob(writer http.ResponseWriter, request *http.R
2626
},
2727
)
2828
if err != nil {
29-
fail(writer, request, http.StatusInternalServerError, "failed to generate cache download URL",
29+
fail(writer, request, http.StatusInternalServerError, "failed to generate cache download URLs",
3030
"key", key, "err", err)
3131

3232
return
3333
}
3434

35-
if len(generateCacheDownloadURLResponse.Urls) != 1 {
35+
if len(generateCacheDownloadURLResponse.Urls) == 0 {
3636
fail(writer, request, http.StatusInternalServerError, fmt.Sprintf("failed to generate"+
37-
" cache download URL: expected 1 URL, got %d", len(generateCacheDownloadURLResponse.Urls)))
37+
" cache download URLs: expected at least 1 URL, got 0"))
3838

3939
return
4040
}
4141

4242
// Retrieve cache entry information
43-
req, err := http.NewRequestWithContext(request.Context(), http.MethodGet,
44-
generateCacheDownloadURLResponse.Urls[0], nil)
43+
for i, url := range generateCacheDownloadURLResponse.Urls {
44+
isLastIteration := i == len(generateCacheDownloadURLResponse.Urls)-1
45+
46+
if azureBlob.retrieveCacheEntryInfo(writer, request, key, url, isLastIteration) {
47+
break
48+
}
49+
}
50+
}
51+
52+
func (azureBlob *AzureBlob) retrieveCacheEntryInfo(
53+
writer http.ResponseWriter,
54+
request *http.Request,
55+
key string,
56+
url string,
57+
isLastIteration bool,
58+
) bool {
59+
req, err := http.NewRequestWithContext(request.Context(), http.MethodGet, url, nil)
4560
if err != nil {
61+
if !isLastIteration {
62+
return false
63+
}
64+
4665
fail(writer, request, http.StatusInternalServerError, "failed to create request to retrieve"+
4766
" cache entry information", "key", key, "err", err)
4867

49-
return
68+
return true
5069
}
5170

5271
resp, err := http.DefaultClient.Do(req)
5372
if err != nil {
73+
if !isLastIteration {
74+
return false
75+
}
76+
5477
fail(writer, request, http.StatusInternalServerError, "failed to perform request to retrieve"+
5578
" cache entry information", "key", key, "err", err)
5679

57-
return
80+
return true
5881
}
5982

6083
// Chacha doesn't support Range requests yet, and not disclosing Content-Length
@@ -66,4 +89,6 @@ func (azureBlob *AzureBlob) headBlob(writer http.ResponseWriter, request *http.R
6689
}
6790

6891
writer.WriteHeader(resp.StatusCode)
92+
93+
return true
6994
}

0 commit comments

Comments
 (0)