From 16d6bf4f814bad353ba9eafdc371ce44de2215fb Mon Sep 17 00:00:00 2001 From: Ben Sarmiento Date: Sun, 22 Oct 2023 14:25:28 +0200 Subject: [PATCH] more efficient caching --- cmd/zurg/main.go | 16 ++++++++-------- internal/dav/propfind.go | 12 +++++++----- internal/torrent/manager.go | 22 ++++++++++++---------- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/cmd/zurg/main.go b/cmd/zurg/main.go index babaa79..77f91aa 100644 --- a/cmd/zurg/main.go +++ b/cmd/zurg/main.go @@ -13,19 +13,19 @@ import ( ) func main() { - c, cErr := config.LoadZurgConfig("./config.yml") - if cErr != nil { - log.Panicf("Config failed to load: %v", cErr) + config, configErr := config.LoadZurgConfig("./config.yml") + if configErr != nil { + log.Panicf("Config failed to load: %v", configErr) } - t := torrent.NewTorrentManager(c) - cache := expirable.NewLRU[string, string](1e4, nil, time.Hour) - mux := http.NewServeMux() - dav.Router(mux, c, t, cache) + t := torrent.NewTorrentManager(config, cache) - addr := fmt.Sprintf(":%s", c.GetPort()) + mux := http.NewServeMux() + dav.Router(mux, config, t, cache) + + addr := fmt.Sprintf(":%s", config.GetPort()) log.Printf("Starting server on %s\n", addr) err := http.ListenAndServe(addr, mux) if err != nil { diff --git a/internal/dav/propfind.go b/internal/dav/propfind.go index a7067a0..b7586c6 100644 --- a/internal/dav/propfind.go +++ b/internal/dav/propfind.go @@ -16,6 +16,8 @@ import ( func HandlePropfindRequest(w http.ResponseWriter, r *http.Request, t *torrent.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) { requestPath := path.Clean(r.URL.Path) + requestPath = strings.Trim(requestPath, "/") + if data, exists := cache.Get(requestPath); exists { w.Header().Set("Content-Type", "text/xml; charset=\"utf-8\"") w.WriteHeader(http.StatusMultiStatus) @@ -26,14 +28,14 @@ func HandlePropfindRequest(w http.ResponseWriter, r *http.Request, t *torrent.To var output []byte var err error - filteredSegments := strings.Split(strings.Trim(requestPath, "/"), "/") + filteredSegments := strings.Split(requestPath, "/") - switch len(filteredSegments) { - case 0: + switch { + case len(filteredSegments) == 1 && filteredSegments[0] == "": output, err = handleRoot(w, r, c) - case 1: + case len(filteredSegments) == 1: output, err = handleListOfTorrents(requestPath, w, r, t, c) - case 2: + case len(filteredSegments) == 2: output, err = handleSingleTorrent(requestPath, w, r, t) default: writeHTTPError(w, "Not Found", http.StatusNotFound) diff --git a/internal/torrent/manager.go b/internal/torrent/manager.go index 4584a6d..1ec04d0 100644 --- a/internal/torrent/manager.go +++ b/internal/torrent/manager.go @@ -11,14 +11,15 @@ import ( "github.com/debridmediamanager.com/zurg/internal/config" "github.com/debridmediamanager.com/zurg/pkg/realdebrid" + "github.com/hashicorp/golang-lru/v2/expirable" ) type TorrentManager struct { - token string torrents []Torrent - workerPool chan bool - config config.ConfigInterface checksum string + config config.ConfigInterface + cache *expirable.LRU[string, string] + workerPool chan bool } func (t *TorrentManager) refreshTorrents() { @@ -30,6 +31,7 @@ func (t *TorrentManager) refreshTorrents() { continue } t.checksum = checksum + t.cache.Purge() t.torrents = t.getAll() for _, torrent := range t.torrents { go func(id string) { @@ -45,11 +47,11 @@ func (t *TorrentManager) refreshTorrents() { // NewTorrentManager creates a new torrent manager // it will fetch all torrents and their info in the background // and store them in-memory -func NewTorrentManager(config config.ConfigInterface) *TorrentManager { +func NewTorrentManager(config config.ConfigInterface, cache *expirable.LRU[string, string]) *TorrentManager { handler := &TorrentManager{ - token: config.GetToken(), - workerPool: make(chan bool, config.GetNumOfWorkers()), config: config, + cache: cache, + workerPool: make(chan bool, config.GetNumOfWorkers()), } // Initialize torrents for the first time @@ -71,7 +73,7 @@ func NewTorrentManager(config config.ConfigInterface) *TorrentManager { } func (t *TorrentManager) getChecksum() string { - torrents, totalCount, err := realdebrid.GetTorrents(t.token, 1) + torrents, totalCount, err := realdebrid.GetTorrents(t.config.GetToken(), 1) if err != nil { log.Printf("Cannot get torrents: %v\n", err) return t.checksum @@ -86,7 +88,7 @@ func (t *TorrentManager) getChecksum() string { func (t *TorrentManager) getAll() []Torrent { log.Println("Getting all torrents") - torrents, totalCount, err := realdebrid.GetTorrents(t.token, 0) + torrents, totalCount, err := realdebrid.GetTorrents(t.config.GetToken(), 0) if err != nil { log.Printf("Cannot get torrents: %v\n", err) return nil @@ -172,7 +174,7 @@ func (t *TorrentManager) getInfo(torrentID string) *Torrent { return torrent } log.Println("Getting info for", torrentID) - info, err := realdebrid.GetTorrentInfo(t.token, torrentID) + info, err := realdebrid.GetTorrentInfo(t.config.GetToken(), torrentID) if err != nil { log.Printf("Cannot get info: %v\n", err) return nil @@ -209,7 +211,7 @@ func (t *TorrentManager) getInfo(torrentID string) *Torrent { defer func() { <-sem }() // Release semaphore unrestrictFn := func() (*realdebrid.UnrestrictResponse, error) { - return realdebrid.UnrestrictCheck(t.token, lnk) + return realdebrid.UnrestrictCheck(t.config.GetToken(), lnk) } resp := realdebrid.RetryUntilOk(unrestrictFn) if resp != nil {