Skip to content

Commit 03e26db

Browse files
authored
feat: improve http download retry strategy (#951)
1 parent 046a3ac commit 03e26db

File tree

1 file changed

+21
-19
lines changed

1 file changed

+21
-19
lines changed

internal/protocol/http/fetcher.go

+21-19
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type chunk struct {
4747
End int64
4848
Downloaded int64
4949

50+
failed bool
5051
retryTimes int
5152
}
5253

@@ -265,10 +266,6 @@ func (f *Fetcher) Wait() (err error) {
265266
return <-f.doneCh
266267
}
267268

268-
type fetchResult struct {
269-
err error
270-
}
271-
272269
func (f *Fetcher) fetch() {
273270
var ctx context.Context
274271
ctx, f.cancel = context.WithCancel(context.Background())
@@ -312,22 +309,35 @@ func (f *Fetcher) fetch() {
312309

313310
func (f *Fetcher) fetchChunk(index int, ctx context.Context) (err error) {
314311
chunk := f.chunks[index]
312+
chunk.failed = false
315313
chunk.retryTimes = 0
316314

317315
var (
318-
client = f.buildClient()
319-
buf = make([]byte, 8192)
320-
maxRetries = 3
316+
client = f.buildClient()
317+
buf = make([]byte, 8192)
321318
)
322319
// retry until all remain chunks failed
323320
for {
324321
// if chunk is completed, return
325322
if f.meta.Res.Range && chunk.Downloaded >= chunk.End-chunk.Begin+1 {
326323
return nil
327324
}
328-
329-
if chunk.retryTimes >= maxRetries {
330-
return
325+
// if all chunks failed, return
326+
if chunk.failed {
327+
allFailed := true
328+
for _, c := range f.chunks {
329+
if !c.failed {
330+
allFailed = false
331+
break
332+
}
333+
}
334+
if allFailed {
335+
if chunk.retryTimes >= 3 {
336+
return
337+
} else {
338+
chunk.retryTimes++
339+
}
340+
}
331341
}
332342

333343
var (
@@ -378,18 +388,10 @@ func (f *Fetcher) fetchChunk(index int, ctx context.Context) (err error) {
378388
return
379389
}
380390
// retry request after 1 second
381-
chunk.retryTimes = chunk.retryTimes + 1
391+
chunk.failed = true
382392
time.Sleep(time.Second)
383393
continue
384394
}
385-
// if chunk is completed, reset other not complete chunks retry times
386-
if err == nil {
387-
for _, c := range f.chunks {
388-
if c != chunk && c.retryTimes > 0 {
389-
c.retryTimes = 0
390-
}
391-
}
392-
}
393395
break
394396
}
395397
return

0 commit comments

Comments
 (0)