fix(downloader): serialize attempt ledger updates

This commit is contained in:
saltbo
2026-07-26 10:39:27 -04:00
parent 5f4f8979b2
commit 1a61b6d9e2
2 changed files with 41 additions and 0 deletions
+4
View File
@@ -46,6 +46,7 @@ type TaskRunner struct {
attempts map[string]int
wg sync.WaitGroup
mu sync.Mutex
attemptMu sync.Mutex
}
type transferSpeeds struct {
@@ -446,6 +447,9 @@ func (w *TaskRunner) resetTaskForAttempt(ctx context.Context, task client.Downlo
w.setMemoryAttempt(task.ID, attempt)
return nil
}
w.attemptMu.Lock()
defer w.attemptMu.Unlock()
ledger, err := loadAttemptLedger(w.cfg.StateDir)
if err != nil {
return fmt.Errorf("load attempt ledger: %w", err)
@@ -12,6 +12,7 @@ import (
"reflect"
"strconv"
"strings"
"sync"
"testing"
"time"
@@ -1368,6 +1369,42 @@ func TestResetTaskForRestartAttemptSkipsAlreadyRecordedAttempt(t *testing.T) {
}
}
func TestResetTaskForAttemptSerializesLedgerUpdates(t *testing.T) {
const taskCount = 64
stateDir := t.TempDir()
w := NewTaskRunnerWithAPI(config.Config{StateDir: stateDir}, nil)
start := make(chan struct{})
errs := make(chan error, taskCount)
var wg sync.WaitGroup
for i := range taskCount {
wg.Add(1)
go func() {
defer wg.Done()
<-start
task := clientTaskWithStatus("task-"+strconv.Itoa(i), "assigned")
errs <- w.resetTaskForAttempt(context.Background(), task, w.logger)
}()
}
close(start)
wg.Wait()
close(errs)
for err := range errs {
if err != nil {
t.Fatal(err)
}
}
ledger, err := loadAttemptLedger(stateDir)
if err != nil {
t.Fatal(err)
}
if len(ledger.Attempts) != taskCount {
t.Fatalf("expected %d attempt records, got %d", taskCount, len(ledger.Attempts))
}
}
func TestRetainSeedKeepsDownloadedResult(t *testing.T) {
dir := t.TempDir()
stateDir := t.TempDir()