diff --git a/internal/app.go b/internal/app.go index 458b470..8f92614 100644 --- a/internal/app.go +++ b/internal/app.go @@ -50,17 +50,42 @@ func MainApp(configPath string) { premium.MonitorPremiumStatus(rd, zurglog) - // extra 1 worker for the refresh job - workerPool, err := ants.NewPool(config.GetNumOfWorkers() + 1) + workerOptions := ants.Options{ + Nonblocking: true, + PanicHandler: func(i interface{}) {}, + Logger: log.Named("worker"), + } + + workerPool, err := ants.NewPool(config.GetNumOfWorkers(), ants.WithOptions(workerOptions)) if err != nil { zurglog.Errorf("Failed to create worker pool: %v", err) os.Exit(1) } defer workerPool.Release() + refreshOptions := ants.Options{ + Nonblocking: true, + PanicHandler: func(i interface{}) {}, + Logger: log.Named("refreshworker"), + } + + // extra 1 worker for the refresh job + refreshPool, err := ants.NewPool(1, ants.WithOptions(refreshOptions)) + if err != nil { + zurglog.Errorf("Failed to create worker pool: %v", err) + os.Exit(1) + } + defer refreshPool.Release() + + repairOptions := ants.Options{ + Nonblocking: true, + PanicHandler: func(i interface{}) {}, + Logger: log.Named("repairworker"), + } + var repairPool *ants.Pool if config.EnableRepair() { - repairPool, err = ants.NewPool(1) + repairPool, err = ants.NewPool(1, ants.WithOptions(repairOptions)) if err != nil { zurglog.Errorf("Failed to create repair pool: %v", err) os.Exit(1) @@ -69,7 +94,7 @@ func MainApp(configPath string) { } utils.EnsureDirExists("data") // Ensure the data directory exists - torrentMgr := torrent.NewTorrentManager(config, rd, workerPool, repairPool, log.Named("manager")) + torrentMgr := torrent.NewTorrentManager(config, rd, workerPool, refreshPool, repairPool, log.Named("manager")) downloadClient := http.NewHTTPClient(config.GetToken(), config.GetRetriesUntilFailed(), config.GetDownloadTimeoutSecs(), true, config, log.Named("dlclient")) downloader := universal.NewDownloader(downloadClient) diff --git a/internal/torrent/manager.go b/internal/torrent/manager.go index 587b759..be04d14 100644 --- a/internal/torrent/manager.go +++ b/internal/torrent/manager.go @@ -32,6 +32,7 @@ type TorrentManager struct { latestState *LibraryState requiredVersion string workerPool *ants.Pool + refreshPool *ants.Pool repairPool *ants.Pool repairTrigger chan *Torrent repairSet mapset.Set[*Torrent] @@ -43,7 +44,7 @@ type TorrentManager struct { // 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, workerPool, repairPool *ants.Pool, log *logutil.Logger) *TorrentManager { +func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, workerPool, refreshPool, repairPool *ants.Pool, log *logutil.Logger) *TorrentManager { t := &TorrentManager{ Config: cfg, Api: api, @@ -56,6 +57,7 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w latestState: &LibraryState{}, requiredVersion: "0.9.3-hotfix.3", workerPool: workerPool, + refreshPool: refreshPool, repairPool: repairPool, log: log, } diff --git a/internal/torrent/repair.go b/internal/torrent/repair.go index 0e160ba..fc16570 100644 --- a/internal/torrent/repair.go +++ b/internal/torrent/repair.go @@ -179,10 +179,13 @@ func (t *TorrentManager) repair(torrent *Torrent) { t.log.Infof("repair_method#1: Torrent %s is still in progress but it should work once done (torrent is temporarily hidden until download has completed)", t.GetKey(torrent)) return } else if info != nil && info.IsDone() && !t.isStillBroken(info, brokenFiles) { - ix := 0 - torrent.SelectedFiles.IterCb(func(_ string, file *File) { - file.Link = info.Links[ix] - ix++ + torrent.SelectedFiles.IterCb(func(_ string, oldFile *File) { + for ix, newFile := range info.Files { + if oldFile.ID == newFile.ID { + oldFile.Link = info.Links[ix] + break + } + } }) t.saveTorrentChangesToDisk(torrent, nil) t.log.Infof("Successfully repaired torrent %s using repair_method#1", t.GetKey(torrent)) @@ -521,12 +524,10 @@ func (t *TorrentManager) handleFixers(fixer realdebrid.Torrent) *Torrent { if info.IsDone() { if !t.isStillBroken(info, brokenFiles) { - ix := 0 - torrent.SelectedFiles.IterCb(func(_ string, file *File) { - for _, brokenFile := range brokenFiles { - if file.ID == brokenFile.ID { - file.Link = info.Links[ix] - ix++ + torrent.SelectedFiles.IterCb(func(_ string, oldFile *File) { + for ix, newFile := range info.Files { + if oldFile.ID == newFile.ID { + oldFile.Link = info.Links[ix] break } } diff --git a/internal/universal/downloader.go b/internal/universal/downloader.go index e6f915f..8089b6f 100644 --- a/internal/universal/downloader.go +++ b/internal/universal/downloader.go @@ -52,7 +52,7 @@ func (dl *Downloader) DownloadFile(directory, torrentName, fileName string, resp return } - log.Debugf("Opening file %s from torrent %s (%s)", fileName, torMgr.GetKey(torrent), file.Link) + // log.Debugf("Opening file %s from torrent %s (%s)", fileName, torMgr.GetKey(torrent), file.Link) unrestrict := torMgr.UnrestrictUntilOk(file.Link) if unrestrict == nil { @@ -102,7 +102,7 @@ func (dl *Downloader) DownloadLink(fileName, link string, resp http.ResponseWrit return } - log.Debugf("Opening file %s (%s)", fileName, link) + // log.Debugf("Opening file %s (%s)", fileName, link) unrestrict := torMgr.UnrestrictUntilOk(link) if unrestrict == nil { @@ -151,17 +151,17 @@ func (dl *Downloader) streamFileToResponse(torrent *intTor.Torrent, file *intTor } // copy range header if it exists - rangeLog := "" + // rangeLog := "" if req.Header.Get("Range") != "" { dlReq.Header.Add("Range", req.Header.Get("Range")) - rangeLog = " (range: " + req.Header.Get("Range") + ")" + // rangeLog = " (range: " + req.Header.Get("Range") + ")" } - if torrent != nil { - log.Debugf("Downloading unrestricted link %s from torrent %s (%s)%s", unrestrict.Download, torMgr.GetKey(torrent), unrestrict.Link, rangeLog) - } else { - log.Debugf("Downloading unrestricted link %s (%s)%s", unrestrict.Download, unrestrict.Link, rangeLog) - } + // if torrent != nil { + // log.Debugf("Downloading unrestricted link %s from torrent %s (%s)%s", unrestrict.Download, torMgr.GetKey(torrent), unrestrict.Link, rangeLog) + // } else { + // log.Debugf("Downloading unrestricted link %s (%s)%s", unrestrict.Download, unrestrict.Link, rangeLog) + // } download, err := dl.client.Do(dlReq) if err != nil { @@ -199,7 +199,7 @@ func (dl *Downloader) streamFileToResponse(torrent *intTor.Torrent, file *intTor } } - log.Debugf("Serving file %s%s", unrestrict.Download, rangeLog) + // log.Debugf("Serving file %s%s", unrestrict.Download, rangeLog) buf := make([]byte, cfg.GetNetworkBufferSize()) io.CopyBuffer(resp, download.Body, buf) diff --git a/pkg/http/client.go b/pkg/http/client.go index dd68ebc..1c48224 100644 --- a/pkg/http/client.go +++ b/pkg/http/client.go @@ -150,9 +150,6 @@ func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) { resp.Body.Close() } r.replaceHostIfNeeded(req) // needed for ipv6 - if !strings.Contains(req.URL.Host, "api.real-debrid.com") { - r.log.Debugf("downloading %s", req.URL) - } resp, err = r.client.Do(req) if resp != nil && resp.StatusCode/100 >= 4 { body, _ := io.ReadAll(resp.Body) diff --git a/pkg/logutil/factory.go b/pkg/logutil/factory.go index 1ed814d..53fd5c2 100644 --- a/pkg/logutil/factory.go +++ b/pkg/logutil/factory.go @@ -93,6 +93,10 @@ func NewLogger(logPath string) *Logger { return zLogger } +func (l *Logger) Printf(format string, v ...interface{}) { + l.SugaredLogger.Infof(format, v...) +} + func (l *Logger) Named(name string) *Logger { return &Logger{ SugaredLogger: l.SugaredLogger.Named(name),