🧱 Chunk is a download manager for slow and unstable servers
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fixing download size to consider last chunk

+14 -15
+3 -2
downloader.go
··· 283 283 ch <- s 284 284 return 285 285 } 286 + written := int64(len(b)) 286 287 if _, err := f.WriteAt(b, c.start); err != nil { 287 288 s.Error = fmt.Errorf("error writing to %s: %w", path, err) 288 289 ch <- s 289 290 return 290 291 } 291 - if err := p.done(idx); err != nil { 292 + if err := p.done(idx, written); err != nil { 292 293 s.Error = fmt.Errorf("error checking chunk #%d as done: %w", idx+1, err) 293 294 ch <- s 294 295 return 295 296 } 296 - s.DownloadedFileBytes = atomic.AddInt64(&downloadedBytes, c.size()) 297 + s.DownloadedFileBytes = atomic.AddInt64(&downloadedBytes, written) 297 298 ch <- s 298 299 }(c, idx, s) 299 300 }
+6 -8
progress.go
··· 36 36 URL string 37 37 Path string 38 38 ChunkSize int64 39 - Chunks []uint32 39 + Chunks []int64 40 40 } 41 41 42 42 // trues to loads a download progress from a file ··· 91 91 } 92 92 93 93 // marks the chunk number `idx` as done (ie successfully downloaded) 94 - func (p *progress) done(idx int) error { 94 + func (p *progress) done(idx int, bytes int64) error { 95 95 if !p.isValidIndex(idx) { 96 96 return fmt.Errorf("%s does not have chunk #%d", p.Path, idx+1) 97 97 } 98 98 p.lock.Lock() 99 99 defer p.lock.Unlock() 100 - atomic.StoreUint32(&p.Chunks[idx], 1) 100 + atomic.StoreInt64(&p.Chunks[idx], bytes) 101 101 f, err := os.Create(p.path) 102 102 if err != nil { 103 103 return fmt.Errorf("error opening progress file %s: %w", p.path, err) ··· 141 141 // calculates the number of bytes downloaded 142 142 func (p *progress) downloadedBytes() int64 { 143 143 var downloaded int64 144 - for idx := range p.Chunks { 145 - if p.Chunks[idx] == 1 { 146 - downloaded += p.ChunkSize 147 - } 144 + for _, c := range p.Chunks { 145 + downloaded += c 148 146 } 149 147 return downloaded 150 148 } ··· 168 166 URL: url, 169 167 Path: abs, 170 168 ChunkSize: chunkSize, 171 - Chunks: make([]uint32, chunks), 169 + Chunks: make([]int64, chunks), 172 170 } 173 171 if err := p.load(restart); err != nil { 174 172 return nil, fmt.Errorf("error loading existing progress file: %w", err)
+5 -5
progress_test.go
··· 14 14 if err != nil { 15 15 t.Errorf("expected no error creating the progress, got %s", err) 16 16 } 17 - if err := p.done(1); err != nil { 17 + if err := p.done(1, 3); err != nil { 18 18 t.Errorf("expected no error marking chunk as done, got %s", err) 19 19 } 20 20 for i := 0; i < 3; i++ { ··· 53 53 wg.Add(1) 54 54 go func(i int) { 55 55 defer wg.Done() 56 - errs <- p.done(i) 56 + errs <- p.done(i, 2048) 57 57 }(i) 58 58 } 59 59 for i := 0; i < 2048; i++ { ··· 78 78 if err != nil { 79 79 t.Errorf("expected no error creating the old progress, got %s", err) 80 80 } 81 - old.done(1) 81 + old.done(1, 3) 82 82 old.close() 83 83 84 84 p, err := newProgress(name, "https://test.etc/chunk.zip", 5, 3, false) ··· 115 115 if err != nil { 116 116 t.Errorf("expected no error creating the old progress, got %s", err) 117 117 } 118 - old.done(1) 118 + old.done(1, 3) 119 119 old.close() 120 120 121 121 if _, err := newProgress(name, "https://test.etc/chunk.zip", 10, 3, false); err == nil { ··· 130 130 if err != nil { 131 131 t.Errorf("expected no error creating the old progress, got %s", err) 132 132 } 133 - old.done(1) 133 + old.done(1, 3) 134 134 old.close() 135 135 136 136 p, err := newProgress(name, "https://test.etc/chunk.zip", 10, 3, true)