diff --git a/internal/app.go b/internal/app.go index 651968f..ed7ef98 100644 --- a/internal/app.go +++ b/internal/app.go @@ -41,15 +41,22 @@ func MainApp(configPath string) { premium.MonitorPremiumStatus(rd, zurglog) - p, err := ants.NewPool(config.GetNumOfWorkers() + 1) + workerPool, err := ants.NewPool(config.GetNumOfWorkers() + 1) if err != nil { zurglog.Errorf("Failed to create worker pool: %v", err) os.Exit(1) } - defer p.Release() + defer workerPool.Release() + + repairPool, err := ants.NewPool(1, ants.WithMaxBlockingTasks(1)) + if err != nil { + zurglog.Errorf("Failed to create repair pool: %v", err) + os.Exit(1) + } + defer repairPool.Release() utils.EnsureDirExists("data") // Ensure the data directory exists - torrentMgr := torrent.NewTorrentManager(config, rd, p, log.Named("manager")) + torrentMgr := torrent.NewTorrentManager(config, rd, workerPool, repairPool, log.Named("manager")) downloadClient := http.NewHTTPClient(config.GetToken(), config.GetRetriesUntilFailed(), 0, true, config, log.Named("dlclient")) downloader := universal.NewDownloader(downloadClient) diff --git a/internal/torrent/manager.go b/internal/torrent/manager.go index c4f192c..14409e6 100644 --- a/internal/torrent/manager.go +++ b/internal/torrent/manager.go @@ -33,13 +33,14 @@ type TorrentManager struct { latestState *LibraryState requiredVersion string workerPool *ants.Pool + repairPool *ants.Pool log *logutil.Logger } // NewTorrentManager creates a new torrent manager // it will fetch all torrents and their info in the background // and store them in-memory and cached in files -func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, p *ants.Pool, log *logutil.Logger) *TorrentManager { +func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, workerPool, repairPool *ants.Pool, log *logutil.Logger) *TorrentManager { t := &TorrentManager{ Config: cfg, Api: api, @@ -51,7 +52,8 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, p allAccessKeys: mapset.NewSet[string](), latestState: &LibraryState{}, requiredVersion: "11.01.2024", - workerPool: p, + workerPool: workerPool, + repairPool: repairPool, log: log, } @@ -149,7 +151,7 @@ func (t *TorrentManager) assignedDirectoryCb(tor *Torrent, cb func(string)) { tor.SelectedFiles.IterCb(func(key string, file *File) { filenames = append(filenames, filepath.Base(file.Path)) fileSizes = append(fileSizes, file.Bytes) - if !tor.Unfixable && unplayable && utils.IsStreamable(file.Path) { + if !tor.Unrepairable && unplayable && utils.IsStreamable(file.Path) { unplayable = false } }) diff --git a/internal/torrent/refresh.go b/internal/torrent/refresh.go index 6c64824..6f3fb19 100644 --- a/internal/torrent/refresh.go +++ b/internal/torrent/refresh.go @@ -224,7 +224,7 @@ func (t *TorrentManager) mergeToMain(existing, toMerge *Torrent) Torrent { Hash: existing.Hash, DownloadedIDs: mapset.NewSet[string](), InProgressIDs: mapset.NewSet[string](), - Unfixable: existing.Unfixable || toMerge.Unfixable, + Unrepairable: existing.Unrepairable || toMerge.Unrepairable, UnassignedLinks: existing.UnassignedLinks.Union(toMerge.UnassignedLinks), BrokenLinks: existing.BrokenLinks.Union(toMerge.BrokenLinks), } diff --git a/internal/torrent/repair.go b/internal/torrent/repair.go index 2bf9396..a85c694 100644 --- a/internal/torrent/repair.go +++ b/internal/torrent/repair.go @@ -17,10 +17,10 @@ const ( ) func (t *TorrentManager) RepairAll() { - _ = t.workerPool.Submit(func() { - t.log.Info("Repairing all broken torrents") + _ = t.repairPool.Submit(func() { + t.log.Info("Checking for broken torrents") t.repairAll() - t.log.Info("Finished repairing all torrents") + t.log.Info("Finished checking for broken torrents") }) } @@ -34,7 +34,7 @@ func (t *TorrentManager) repairAll() { hashGroups = append(hashGroups, currentGroup) allTorrents.IterCb(func(_ string, torrent *Torrent) { - if torrent.AnyInProgress() || torrent.Unfixable { + if torrent.AnyInProgress() || torrent.Unrepairable { return } if currentGroup.Cardinality() >= maxGroupSize { @@ -69,7 +69,7 @@ func (t *TorrentManager) repairAll() { var toRepair []*Torrent allTorrents.IterCb(func(_ string, torrent *Torrent) { - if torrent.AnyInProgress() || torrent.Unfixable { + if torrent.AnyInProgress() || torrent.Unrepairable { return } @@ -100,16 +100,15 @@ func (t *TorrentManager) repairAll() { } func (t *TorrentManager) Repair(torrent *Torrent) { + if torrent.Unrepairable { + t.log.Warnf("Torrent %s is unfixable, skipping repair", t.GetKey(torrent)) + return + } if repairing, ok := t.Repairs.Get(t.GetKey(torrent)); ok && repairing { t.log.Warnf("Torrent %s is already being repaired, skipping repair", t.GetKey(torrent)) return } t.Repairs.Set(t.GetKey(torrent), true) - - if torrent.Unfixable { - t.log.Warnf("Torrent %s is unfixable, skipping repair", t.GetKey(torrent)) - return - } // save the broken files to the file cache infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE) torrent.DownloadedIDs.Each(func(id string) bool { @@ -391,11 +390,11 @@ func (t *TorrentManager) markAsUnplayable(torrent *Torrent) { func (t *TorrentManager) markAsUnfixable(torrent *Torrent) { t.log.Warnf("Marking torrent %s as unfixable", t.GetKey(torrent)) - torrent.Unfixable = true + torrent.Unrepairable = true infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE) torrent.DownloadedIDs.Each(func(id string) bool { info, _ := infoCache.Get(id) - info.Unfixable = true + info.Unrepairable = true t.writeTorrentToFile(id, info) return false }) diff --git a/internal/torrent/types.go b/internal/torrent/types.go index 27d3f37..f609659 100644 --- a/internal/torrent/types.go +++ b/internal/torrent/types.go @@ -23,7 +23,7 @@ type Torrent struct { OriginalName string `json:"OriginalName"` // immutable Rename string `json:"Rename"` // modified over time SelectedFiles cmap.ConcurrentMap[string, *File] `json:"-"` // modified over time - Unfixable bool `json:"Unfixable"` // modified over time + Unrepairable bool `json:"Unfixable"` // modified over time BrokenLinks mapset.Set[string] `json:"BrokenLinks"` // only relevant on repair Version string `json:"Version"` // only used for files