Repair logic

This commit is contained in:
Ben Sarmiento
2024-01-14 12:37:37 +01:00
parent 343a3218eb
commit 6a5bc79852
4 changed files with 48 additions and 9 deletions

View File

@@ -28,6 +28,7 @@ type TorrentManager struct {
DownloadCache cmap.ConcurrentMap[string, *realdebrid.Download]
DownloadMap cmap.ConcurrentMap[string, *realdebrid.Download]
allAccessKeys mapset.Set[string]
forRepairs mapset.Set[string]
latestState *LibraryState
requiredVersion string
workerPool *ants.Pool
@@ -42,6 +43,7 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, p
Config: cfg,
Api: api,
allAccessKeys: mapset.NewSet[string](),
forRepairs: mapset.NewSet[string](),
latestState: &LibraryState{},
requiredVersion: "11.01.2024",
workerPool: p,

View File

@@ -37,12 +37,22 @@ func (t *TorrentManager) RefreshTorrents() []string {
freshKeys := mapset.NewSet[string]()
allTorrents, _ := t.DirectoryMap.Get(INT_ALL)
toReinsert := mapset.NewSet[string]()
noInfoCount := 0
for info := range infoChan {
if info == nil {
noInfoCount++
continue
}
torrentID := info.DownloadedIDs.ToSlice()[0]
if !info.AnyInProgress() && t.forRepairs.Contains(torrentID) {
// if it's 100% and it's a temp repair, remove it
t.Api.DeleteTorrent(torrentID)
toReinsert.Add(t.GetKey(info))
infoChan <- nil
t.forRepairs.Remove(torrentID)
continue
}
if !info.AnyInProgress() {
freshKeys.Add(t.GetKey(info))
}
@@ -54,6 +64,7 @@ func (t *TorrentManager) RefreshTorrents() []string {
}
}
t.log.Infof("Compiled into %d torrents, %d were missing info", allTorrents.Count(), noInfoCount)
var updatedPaths []string
// torrents yet to be assigned in a directory
freshKeys.Difference(t.allAccessKeys).Each(func(accessKey string) bool {
@@ -82,6 +93,12 @@ func (t *TorrentManager) RefreshTorrents() []string {
return false
})
toReinsert.Each(func(accessKey string) bool {
torrent, _ := allTorrents.Get(accessKey)
t.reinsertTorrent(torrent, "")
return false
})
return updatedPaths
}

View File

@@ -14,7 +14,6 @@ import (
const (
EXPIRED_LINK_TOLERANCE_HOURS = 24
REPAIR_SEMAPHORE = "semaphore"
)
func (t *TorrentManager) RepairAll() {
@@ -119,7 +118,6 @@ func (t *TorrentManager) Repair(torrent *Torrent) {
_ = t.workerPool.Submit(func() {
t.log.Infof("Repairing torrent %s", t.GetKey(torrent))
t.repair(torrent)
torrent.InProgressIDs.Remove(REPAIR_SEMAPHORE)
t.log.Infof("Finished repairing torrent %s", t.GetKey(torrent))
})
}
@@ -129,7 +127,6 @@ func (t *TorrentManager) repair(torrent *Torrent) {
t.log.Infof("Torrent %s is in progress, skipping repair until download is done", t.GetKey(torrent))
return
}
torrent.InProgressIDs.Add(REPAIR_SEMAPHORE)
proceed := t.canCapacityHandle() // blocks for approx 45 minutes if active torrents are full
if !proceed {
@@ -249,8 +246,10 @@ func (t *TorrentManager) repair(torrent *Torrent) {
}
func (t *TorrentManager) reinsertTorrent(torrent *Torrent, brokenFiles string) bool {
oldTorrentIDs := make([]string, 0)
// broken files means broken links
oldTorrentIDs := make([]string, 0)
// if brokenFiles is not provided
if brokenFiles == "" {
// only replace the torrent if we are reinserting all files
@@ -294,7 +293,17 @@ func (t *TorrentManager) reinsertTorrent(torrent *Torrent, brokenFiles string) b
return false
}
if info.Status == "magnet_error" || info.Status == "error" || info.Status == "virus" || info.Status == "dead" {
// documented status: magnet_error, magnet_conversion, waiting_files_selection, queued, downloading, downloaded, error, virus, compressing, uploading, dead
okStatuses := []string{"magnet_conversion", "waiting_files_selection", "queued", "downloading", "downloaded", "uploading"}
// not compressing because we need playable files
isOkStatus := false
for _, status := range okStatuses {
if info.Status == status {
isOkStatus = true
break
}
}
if !isOkStatus {
t.log.Warnf("The redownloaded torrent id=%s is in error state: %s", newTorrentID, info.Status)
t.Api.DeleteTorrent(newTorrentID)
return false
@@ -302,8 +311,13 @@ func (t *TorrentManager) reinsertTorrent(torrent *Torrent, brokenFiles string) b
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)
for _, id := range oldTorrentIDs {
t.Api.DeleteTorrent(id)
t.forRepairs.Add(newTorrentID)
if len(oldTorrentIDs) > 0 {
for _, id := range oldTorrentIDs {
t.Api.DeleteTorrent(id)
}
} else {
t.forRepairs.Add(newTorrentID)
}
return true
}
@@ -316,8 +330,13 @@ func (t *TorrentManager) reinsertTorrent(torrent *Torrent, brokenFiles string) b
}
t.log.Infof("Repair successful id=%s", newTorrentID)
for _, id := range oldTorrentIDs {
t.Api.DeleteTorrent(id)
t.forRepairs.Add(newTorrentID)
if len(oldTorrentIDs) > 0 {
for _, id := range oldTorrentIDs {
t.Api.DeleteTorrent(id)
}
} else {
t.forRepairs.Add(newTorrentID)
}
return true
}