From bacee5178a2b099e20f7d21e36619fb1eebaf248 Mon Sep 17 00:00:00 2001 From: Ben Sarmiento Date: Fri, 19 Jan 2024 01:06:18 +0100 Subject: [PATCH] Ensure only 1 instance is being fixed --- internal/torrent/manager.go | 4 ++-- internal/torrent/repair.go | 42 ++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/internal/torrent/manager.go b/internal/torrent/manager.go index 14409e6..bb6aa40 100644 --- a/internal/torrent/manager.go +++ b/internal/torrent/manager.go @@ -27,8 +27,8 @@ type TorrentManager struct { DirectoryMap cmap.ConcurrentMap[string, cmap.ConcurrentMap[string, *Torrent]] // directory -> accessKey -> Torrent DownloadCache cmap.ConcurrentMap[string, *realdebrid.Download] DownloadMap cmap.ConcurrentMap[string, *realdebrid.Download] - Repairs cmap.ConcurrentMap[string, bool] onlyForRepair cmap.ConcurrentMap[string, *Torrent] + Repairs mapset.Set[string] allAccessKeys mapset.Set[string] latestState *LibraryState requiredVersion string @@ -48,7 +48,7 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w DownloadCache: cmap.New[*realdebrid.Download](), DownloadMap: cmap.New[*realdebrid.Download](), onlyForRepair: cmap.New[*Torrent](), - Repairs: cmap.New[bool](), + Repairs: mapset.NewSet[string](), allAccessKeys: mapset.NewSet[string](), latestState: &LibraryState{}, requiredVersion: "11.01.2024", diff --git a/internal/torrent/repair.go b/internal/torrent/repair.go index 9720e83..868504a 100644 --- a/internal/torrent/repair.go +++ b/internal/torrent/repair.go @@ -67,7 +67,7 @@ func (t *TorrentManager) repairAll() { } t.log.Debugf("Found %d torrents that are no longer cached", uncachedCount) - var toRepair []*Torrent + toRepair := mapset.NewSet[*Torrent]() allTorrents.IterCb(func(_ string, torrent *Torrent) { if torrent.AnyInProgress() || torrent.Unrepairable { return @@ -83,20 +83,20 @@ func (t *TorrentManager) repairAll() { // check 2: for broken files hasBrokenFiles := false torrent.SelectedFiles.IterCb(func(_ string, file *File) { - if file.Link == "repair" || file.Link == "" { + if !strings.HasPrefix(file.Link, "http") && file.Link != "unselect" { hasBrokenFiles = true } }) if !isCached || hasBrokenFiles || torrent.UnassignedLinks.Cardinality() > 0 { - toRepair = append(toRepair, torrent) + toRepair.Add(torrent) } }) - t.log.Debugf("Found %d broken torrents to repair in total", len(toRepair)) - for i := range toRepair { - torrent := toRepair[i] + t.log.Debugf("Found %d broken torrents to repair in total", toRepair.Cardinality()) + toRepair.Each(func(torrent *Torrent) bool { t.Repair(torrent) - } + return false + }) } func (t *TorrentManager) Repair(torrent *Torrent) { @@ -104,11 +104,11 @@ func (t *TorrentManager) Repair(torrent *Torrent) { t.log.Warnf("Torrent %s is unfixable, skipping repair", t.GetKey(torrent)) return } - if repairing, ok := t.Repairs.Get(t.GetKey(torrent)); ok && repairing { + if t.Repairs.Contains(t.GetKey(torrent)) { t.log.Warnf("Torrent %s is already being repaired, skipping repair", t.GetKey(torrent)) return } - t.Repairs.Set(t.GetKey(torrent), true) + t.Repairs.Add(t.GetKey(torrent)) // save the broken files to the file cache infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE) torrent.DownloadedIDs.Each(func(id string) bool { @@ -116,7 +116,7 @@ func (t *TorrentManager) Repair(torrent *Torrent) { info.SelectedFiles.IterCb(func(_ string, file *File) { torrent.BrokenLinks.Each(func(link string) bool { if file.Link == link { - file.Link = "repair" + file.Link = "" } return file.Link == link }) @@ -125,14 +125,13 @@ func (t *TorrentManager) Repair(torrent *Torrent) { return false }) _ = t.workerPool.Submit(func() { - t.log.Infof("Repairing torrent %s", t.GetKey(torrent)) t.repair(torrent) t.Repairs.Remove(t.GetKey(torrent)) - t.log.Infof("Finished repairing torrent %s", t.GetKey(torrent)) }) } func (t *TorrentManager) repair(torrent *Torrent) { + t.log.Infof("Attempting repair for torrent %s", t.GetKey(torrent)) if torrent.AnyInProgress() { t.log.Infof("Torrent %s is in progress, skipping repair until download is done", t.GetKey(torrent)) return @@ -192,6 +191,7 @@ func (t *TorrentManager) repair(torrent *Torrent) { t.log.Warnf("Torrent %s is rar'ed and we cannot repair it, deleting it as configured", t.GetKey(torrent)) t.Delete(t.GetKey(torrent), true) } else { + t.log.Warnf("Torrent %s is rar'ed and we cannot repair it, skipping repair", t.GetKey(torrent)) newUnassignedLinks.IterCb(func(_ string, unassigned *realdebrid.Download) { if unassigned == nil { return @@ -220,24 +220,24 @@ func (t *TorrentManager) repair(torrent *Torrent) { t.log.Debugf("During repair, zurg found %d broken files for torrent %s", len(brokenFiles), t.GetKey(torrent)) // first solution: reinsert and see if the broken file is now working - t.log.Debugf("Repair_try#1: Trying to redownload torrent %s to repair it", t.GetKey(torrent)) + t.log.Debugf("repair_method#1: Trying to redownload torrent %s to repair it", t.GetKey(torrent)) info, err := t.redownloadTorrent(torrent, "") if err != nil { t.log.Warnf("Cannot repair torrent %s", t.GetKey(torrent)) } else if info.Progress != 100 || (info.Progress == 100 && !t.isStillBroken(info, brokenFiles)) { - t.log.Infof("Successfully repaired torrent %s", t.GetKey(torrent)) + t.log.Infof("Successfully repaired torrent %s using repair_method#1", t.GetKey(torrent)) return } // second solution: add only the broken files if len(brokenFiles) > 0 { - t.log.Infof("Repair_try#2: Redownloading %dof%d broken files for torrent %s", len(brokenFiles), torrent.SelectedFiles.Count(), t.GetKey(torrent)) + t.log.Infof("repair_method#2: Redownloading %dof%d broken files for torrent %s", len(brokenFiles), torrent.SelectedFiles.Count(), t.GetKey(torrent)) brokenFileIDs := strings.Join(getFileIDs(brokenFiles), ",") _, err := t.redownloadTorrent(torrent, brokenFileIDs) if err != nil { t.log.Warnf("Cannot repair torrent %s", t.GetKey(torrent)) } else { - t.log.Infof("Successfully repaired torrent %s", t.GetKey(torrent)) + t.log.Infof("Successfully repaired torrent %s using repair_method#2", t.GetKey(torrent)) } } else { t.log.Warnf("Torrent %s has no broken files to repair", t.GetKey(torrent)) @@ -286,7 +286,7 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, brokenFiles string) info, err := t.Api.GetTorrentInfo(newTorrentID) if err != nil { t.Api.DeleteTorrent(newTorrentID) - return nil, fmt.Errorf("cannot get info on redownloaded torrent id=%s : %v", newTorrentID, err) + return nil, fmt.Errorf("cannot get info on redownloaded torrent %s (id=%s) : %v", t.GetKey(torrent), newTorrentID, err) } // documented status: magnet_error, magnet_conversion, waiting_files_selection, queued, downloading, downloaded, error, virus, compressing, uploading, dead @@ -301,11 +301,11 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, brokenFiles string) } if !isOkStatus { t.Api.DeleteTorrent(newTorrentID) - return nil, fmt.Errorf("the redownloaded torrent id=%s is in error state: %s", newTorrentID, info.Status) + return nil, fmt.Errorf("the redownloaded torrent %s (id=%s) is in error state: %s", t.GetKey(torrent), newTorrentID, info.Status) } if info.Progress != 100 { - t.log.Infof("Torrent id=%s is not cached anymore so we have to wait until completion (this should fix the issue already)", info.ID) + t.log.Infof("Torrent %s (id=%s) is not cached anymore so we have to wait until completion (this should fix the issue already)", t.GetKey(torrent), info.ID) if len(oldTorrentIDs) > 0 { // only triggered when brokenFiles == "" for _, id := range oldTorrentIDs { @@ -320,10 +320,10 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, brokenFiles string) brokenCount := len(strings.Split(brokenFiles, ",")) if len(info.Links) != brokenCount { t.Api.DeleteTorrent(newTorrentID) - return nil, fmt.Errorf("it did not fix the issue for id=%s, only got %d files but we need %d, undoing", info.ID, len(info.Links), brokenCount) + return nil, fmt.Errorf("it did not fix the issue for %s (id=%s), only got %d files but we need %d, undoing", t.GetKey(torrent), info.ID, len(info.Links), brokenCount) } - t.log.Infof("Redownload successful id=%s", newTorrentID) + t.log.Infof("Redownload successful %s (id=%s)", t.GetKey(torrent), newTorrentID) if len(oldTorrentIDs) > 0 { // only triggered when brokenFiles == "" for _, id := range oldTorrentIDs {