replace mutex with atomic ops to reduce syscalls (#4)

This commit is contained in:
dogghi no 2025-04-17 10:33:36 +02:00 committed by GitHub
parent 3848ff086b
commit 4a15dd0761
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -12,6 +12,7 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"sync" "sync"
"sync/atomic"
"time" "time"
"govd/models" "govd/models"
@ -261,9 +262,8 @@ func runChunkedDownload(
var downloadErr error var downloadErr error
var errOnce sync.Once var errOnce sync.Once
var completedChunks int64 var completedChunks atomic.Int64
var completedBytes int64 var completedBytes atomic.Int64
var progressMutex sync.Mutex
downloadCtx, cancelDownload := context.WithCancel(ctx) downloadCtx, cancelDownload := context.WithCancel(ctx)
defer cancelDownload() defer cancelDownload()
@ -303,11 +303,9 @@ func runChunkedDownload(
// update progress // update progress
chunkSize := chunk[1] - chunk[0] + 1 chunkSize := chunk[1] - chunk[0] + 1
progressMutex.Lock() completedChunks.Add(1)
completedChunks++ completedBytes.Add(int64(chunkSize))
completedBytes += int64(chunkSize) progress := float64(completedBytes.Load()) / float64(fileSize)
progress := float64(completedBytes) / float64(fileSize)
progressMutex.Unlock()
// report progress if handler exists // report progress if handler exists
if config.ProgressUpdater != nil { if config.ProgressUpdater != nil {
@ -492,13 +490,12 @@ func downloadSegments(
var wg sync.WaitGroup var wg sync.WaitGroup
errChan := make(chan error, len(segmentURLs)) errChan := make(chan error, len(segmentURLs))
var errMutex sync.Mutex
var firstErr error var firstErr atomic.Value
downloadedFiles := make([]string, len(segmentURLs)) downloadedFiles := make([]string, len(segmentURLs))
defer func() { defer func() {
if firstErr != nil { if firstErr.Load() != nil {
for _, path := range downloadedFiles { for _, path := range downloadedFiles {
if path != "" { if path != "" {
os.Remove(path) os.Remove(path)
@ -541,12 +538,10 @@ func downloadSegments(
}) })
if err != nil { if err != nil {
errMutex.Lock() if firstErr.Load() == nil {
if firstErr == nil { firstErr.Store(fmt.Errorf("failed to download segment %d: %w", idx, err))
firstErr = fmt.Errorf("failed to download segment %d: %w", idx, err)
cancelDownload() // Cancella tutte le altre download cancelDownload() // Cancella tutte le altre download
} }
errMutex.Unlock()
return return
} }