fix(downloader): report aria2 metadata runtime

This commit is contained in:
saltbo
2026-06-29 20:19:46 -04:00
parent 979afd20e7
commit 74c0d0cd75
2 changed files with 65 additions and 9 deletions
+28 -5
View File
@@ -566,7 +566,7 @@ func addAria2Task(ctx context.Context, aria *arigo.Client, task downloader.Downl
func (a Aria2) waitResult(ctx context.Context, aria **arigo.Client, task downloader.DownloadTask, taskDir string, gid string, progress downloader.ProgressReporter) (downloader.Result, error) {
initialProgress := progress
if task.SourceType() != "http" {
initialProgress = func(downloader.ProgressUpdate) error { return nil }
initialProgress = reportMetadataProgress(progress)
}
primaryGID := gid
status, err := a.waitAria2(ctx, aria, task, primaryGID, initialProgress)
@@ -970,6 +970,19 @@ func (a Aria2) waitAria2(ctx context.Context, aria **arigo.Client, task download
}
}
func reportMetadataProgress(progress downloader.ProgressReporter) downloader.ProgressReporter {
return func(update downloader.ProgressUpdate) error {
update.Downloaded = 0
update.Total = nil
update.Bps = 0
if update.Runtime != nil {
update.Runtime.Phase = "metadata"
update.Runtime.ETASeconds = nil
}
return progress(update)
}
}
func (a Aria2) getAria2Peers(ctx context.Context, aria **arigo.Client, gid string) []arigo.Peer {
peers, err := (*aria).GetPeers(gid)
if err == nil {
@@ -1028,7 +1041,7 @@ func aria2Detail(status arigo.Status, peers []arigo.Peer, geoIP geoip.Resolver)
uploadBps := int64(status.UploadSpeed)
detail := &downloader.TaskRuntime{
Engine: "aria2",
Phase: aria2Phase(string(status.Status), status.FollowedBy),
Phase: aria2Phase(status),
State: string(status.Status),
ETASeconds: aria2ETA(status),
Connections: &connections,
@@ -1065,14 +1078,17 @@ func aria2ETA(status arigo.Status) *int64 {
return &eta
}
func aria2Phase(state string, followedBy []string) string {
switch state {
func aria2Phase(status arigo.Status) string {
switch string(status.Status) {
case string(arigo.StatusWaiting):
if len(followedBy) > 0 {
if len(status.FollowedBy) > 0 {
return "metadata"
}
return "downloading"
case string(arigo.StatusActive):
if !hasAria2LocalFile(status.Files) && system.IsAria2MetadataPath(firstAria2FilePath(status.Files)) {
return "metadata"
}
return "downloading"
case "complete", string(arigo.StatusCompleted):
return "completed"
@@ -1083,6 +1099,13 @@ func aria2Phase(state string, followedBy []string) string {
}
}
func firstAria2FilePath(files []arigo.File) string {
if len(files) == 0 {
return ""
}
return files[0].Path
}
func aria2Trackers(announceList [][]string) []downloader.Tracker {
trackers := make([]downloader.Tracker, 0, 20)
seen := map[string]struct{}{}
+37 -4
View File
@@ -342,16 +342,19 @@ func TestAria2StatusMatchingHelpers(t *testing.T) {
}
func TestAria2RuntimeConversionHelpers(t *testing.T) {
if got := aria2Phase(string(arigo.StatusWaiting), []string{"child"}); got != "metadata" {
if got := aria2Phase(arigo.Status{Status: arigo.StatusWaiting, FollowedBy: []string{"child"}}); got != "metadata" {
t.Fatalf("expected metadata phase, got %s", got)
}
if got := aria2Phase(string(arigo.StatusWaiting), nil); got != "downloading" {
if got := aria2Phase(arigo.Status{Status: arigo.StatusActive, Files: []arigo.File{{Path: "[METADATA]fixture"}}}); got != "metadata" {
t.Fatalf("expected active metadata phase, got %s", got)
}
if got := aria2Phase(arigo.Status{Status: arigo.StatusWaiting}); got != "downloading" {
t.Fatalf("expected waiting download phase, got %s", got)
}
if got := aria2Phase(string(arigo.StatusCompleted), nil); got != "completed" {
if got := aria2Phase(arigo.Status{Status: arigo.StatusCompleted}); got != "completed" {
t.Fatalf("expected completed phase, got %s", got)
}
if got := aria2Phase(string(arigo.StatusRemoved), nil); got != "error" {
if got := aria2Phase(arigo.Status{Status: arigo.StatusRemoved}); got != "error" {
t.Fatalf("expected removed phase error, got %s", got)
}
if aria2PeerProgress(arigo.Peer{}) != nil {
@@ -385,6 +388,36 @@ func TestAria2RuntimeConversionHelpers(t *testing.T) {
}
}
func TestReportMetadataProgressKeepsRuntimeButHidesMetadataBytes(t *testing.T) {
total := int64(14151)
var got downloader.ProgressUpdate
reporter := reportMetadataProgress(func(update downloader.ProgressUpdate) error {
got = update
return nil
})
err := reporter(downloader.ProgressUpdate{
Downloaded: 1024,
Total: &total,
Bps: 512,
Runtime: &downloader.TaskRuntime{
Engine: "aria2",
Phase: "downloading",
ETASeconds: &total,
Trackers: []downloader.Tracker{{URL: "udp://tracker.example:1337/announce"}},
},
})
if err != nil {
t.Fatal(err)
}
if got.Downloaded != 0 || got.Total != nil || got.Bps != 0 {
t.Fatalf("metadata progress must not expose metadata bytes, got %#v", got)
}
if got.Runtime == nil || got.Runtime.Phase != "metadata" || got.Runtime.ETASeconds != nil || len(got.Runtime.Trackers) != 1 {
t.Fatalf("expected metadata runtime with trackers, got %#v", got.Runtime)
}
}
func TestAria2FilesDetailAndResultHelpers(t *testing.T) {
taskDir := t.TempDir()
contentPath := filepath.Join(taskDir, "Torrent", "movie.mkv")