mirror of
https://github.com/saltbo/zpan.git
synced 2026-08-29 00:01:42 +08:00
fix(downloader): make aria2 reset idempotent
This commit is contained in:
@@ -144,11 +144,18 @@ func (a Aria2) ResetTask(ctx context.Context, task client.DownloadTask) error {
|
||||
if !aria2StatusBelongsToTask(status, taskDir, aria2TaskGID(task.ID)) {
|
||||
continue
|
||||
}
|
||||
if err := aria.ForceRemove(status.GID); err != nil {
|
||||
resetErrs = append(resetErrs, fmt.Errorf("force remove aria2 gid %s: %w", status.GID, err))
|
||||
removeActive, removeResult := aria2ResetOperations(status)
|
||||
if removeActive {
|
||||
err := aria.ForceRemove(status.GID)
|
||||
if err != nil && !isAria2DownloadNotFound(err) {
|
||||
resetErrs = append(resetErrs, fmt.Errorf("force remove aria2 gid %s: %w", status.GID, err))
|
||||
}
|
||||
}
|
||||
if err := aria.RemoveDownloadResult(status.GID); err != nil {
|
||||
resetErrs = append(resetErrs, fmt.Errorf("remove aria2 result %s: %w", status.GID, err))
|
||||
if removeResult {
|
||||
err := aria.RemoveDownloadResult(status.GID)
|
||||
if err != nil && !isAria2DownloadNotFound(err) {
|
||||
resetErrs = append(resetErrs, fmt.Errorf("remove aria2 result %s: %w", status.GID, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := os.RemoveAll(taskDir); err != nil {
|
||||
@@ -157,6 +164,25 @@ func (a Aria2) ResetTask(ctx context.Context, task client.DownloadTask) error {
|
||||
return errors.Join(resetErrs...)
|
||||
}
|
||||
|
||||
func aria2ResetOperations(status arigo.Status) (removeActive bool, removeResult bool) {
|
||||
switch string(status.Status) {
|
||||
case string(arigo.StatusCompleted), string(arigo.StatusError), string(arigo.StatusRemoved), "complete":
|
||||
return false, true
|
||||
case string(arigo.StatusActive), string(arigo.StatusWaiting), string(arigo.StatusPaused):
|
||||
return true, true
|
||||
default:
|
||||
return true, true
|
||||
}
|
||||
}
|
||||
|
||||
func isAria2DownloadNotFound(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
msg := strings.ToLower(err.Error())
|
||||
return strings.Contains(msg, "download") && strings.Contains(msg, "not found")
|
||||
}
|
||||
|
||||
func (a Aria2) SaveSession(ctx context.Context) error {
|
||||
client, err := a.client(ctx)
|
||||
if err != nil {
|
||||
|
||||
@@ -150,6 +150,49 @@ func TestAria2StartArgsForceSaveCompletedSeeds(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAria2ResetOperations(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
status arigo.DownloadStatus
|
||||
wantRemoveActive bool
|
||||
wantRemoveResult bool
|
||||
}{
|
||||
{name: "active", status: arigo.StatusActive, wantRemoveActive: true, wantRemoveResult: true},
|
||||
{name: "waiting", status: arigo.StatusWaiting, wantRemoveActive: true, wantRemoveResult: true},
|
||||
{name: "paused", status: arigo.StatusPaused, wantRemoveActive: true, wantRemoveResult: true},
|
||||
{name: "completed", status: arigo.StatusCompleted, wantRemoveActive: false, wantRemoveResult: true},
|
||||
{name: "error", status: arigo.StatusError, wantRemoveActive: false, wantRemoveResult: true},
|
||||
{name: "removed", status: arigo.StatusRemoved, wantRemoveActive: false, wantRemoveResult: true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
removeActive, removeResult := aria2ResetOperations(arigo.Status{Status: tt.status})
|
||||
if removeActive != tt.wantRemoveActive || removeResult != tt.wantRemoveResult {
|
||||
t.Fatalf(
|
||||
"expected removeActive=%v removeResult=%v, got removeActive=%v removeResult=%v",
|
||||
tt.wantRemoveActive,
|
||||
tt.wantRemoveResult,
|
||||
removeActive,
|
||||
removeResult,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsAria2DownloadNotFound(t *testing.T) {
|
||||
if !isAria2DownloadNotFound(errors.New("Active Download not found for GID#b384ccaa7eae88da")) {
|
||||
t.Fatal("expected aria2 active download not found to be ignored during reset")
|
||||
}
|
||||
if !isAria2DownloadNotFound(errors.New("Download result not found for GID#b384ccaa7eae88da")) {
|
||||
t.Fatal("expected aria2 download result not found to be ignored during reset")
|
||||
}
|
||||
if isAria2DownloadNotFound(errors.New("aria2 download ended with status error")) {
|
||||
t.Fatal("expected ordinary aria2 download errors to stay visible")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPDownloadResumesExistingFile(t *testing.T) {
|
||||
var rangeHeader string
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user