more efficient caching

This commit is contained in:
Ben Sarmiento
2023-10-22 14:25:28 +02:00
parent 6eccba394c
commit 16d6bf4f81
3 changed files with 27 additions and 23 deletions

View File

@@ -13,19 +13,19 @@ import (
) )
func main() { func main() {
c, cErr := config.LoadZurgConfig("./config.yml") config, configErr := config.LoadZurgConfig("./config.yml")
if cErr != nil { if configErr != nil {
log.Panicf("Config failed to load: %v", cErr) log.Panicf("Config failed to load: %v", configErr)
} }
t := torrent.NewTorrentManager(c)
cache := expirable.NewLRU[string, string](1e4, nil, time.Hour) cache := expirable.NewLRU[string, string](1e4, nil, time.Hour)
mux := http.NewServeMux() t := torrent.NewTorrentManager(config, cache)
dav.Router(mux, c, t, 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) log.Printf("Starting server on %s\n", addr)
err := http.ListenAndServe(addr, mux) err := http.ListenAndServe(addr, mux)
if err != nil { if err != nil {

View File

@@ -16,6 +16,8 @@ import (
func HandlePropfindRequest(w http.ResponseWriter, r *http.Request, t *torrent.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) { 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 := path.Clean(r.URL.Path)
requestPath = strings.Trim(requestPath, "/")
if data, exists := cache.Get(requestPath); exists { if data, exists := cache.Get(requestPath); exists {
w.Header().Set("Content-Type", "text/xml; charset=\"utf-8\"") w.Header().Set("Content-Type", "text/xml; charset=\"utf-8\"")
w.WriteHeader(http.StatusMultiStatus) w.WriteHeader(http.StatusMultiStatus)
@@ -26,14 +28,14 @@ func HandlePropfindRequest(w http.ResponseWriter, r *http.Request, t *torrent.To
var output []byte var output []byte
var err error var err error
filteredSegments := strings.Split(strings.Trim(requestPath, "/"), "/") filteredSegments := strings.Split(requestPath, "/")
switch len(filteredSegments) { switch {
case 0: case len(filteredSegments) == 1 && filteredSegments[0] == "":
output, err = handleRoot(w, r, c) output, err = handleRoot(w, r, c)
case 1: case len(filteredSegments) == 1:
output, err = handleListOfTorrents(requestPath, w, r, t, c) output, err = handleListOfTorrents(requestPath, w, r, t, c)
case 2: case len(filteredSegments) == 2:
output, err = handleSingleTorrent(requestPath, w, r, t) output, err = handleSingleTorrent(requestPath, w, r, t)
default: default:
writeHTTPError(w, "Not Found", http.StatusNotFound) writeHTTPError(w, "Not Found", http.StatusNotFound)

View File

@@ -11,14 +11,15 @@ import (
"github.com/debridmediamanager.com/zurg/internal/config" "github.com/debridmediamanager.com/zurg/internal/config"
"github.com/debridmediamanager.com/zurg/pkg/realdebrid" "github.com/debridmediamanager.com/zurg/pkg/realdebrid"
"github.com/hashicorp/golang-lru/v2/expirable"
) )
type TorrentManager struct { type TorrentManager struct {
token string
torrents []Torrent torrents []Torrent
workerPool chan bool
config config.ConfigInterface
checksum string checksum string
config config.ConfigInterface
cache *expirable.LRU[string, string]
workerPool chan bool
} }
func (t *TorrentManager) refreshTorrents() { func (t *TorrentManager) refreshTorrents() {
@@ -30,6 +31,7 @@ func (t *TorrentManager) refreshTorrents() {
continue continue
} }
t.checksum = checksum t.checksum = checksum
t.cache.Purge()
t.torrents = t.getAll() t.torrents = t.getAll()
for _, torrent := range t.torrents { for _, torrent := range t.torrents {
go func(id string) { go func(id string) {
@@ -45,11 +47,11 @@ func (t *TorrentManager) refreshTorrents() {
// NewTorrentManager creates a new torrent manager // NewTorrentManager creates a new torrent manager
// it will fetch all torrents and their info in the background // it will fetch all torrents and their info in the background
// and store them in-memory // and store them in-memory
func NewTorrentManager(config config.ConfigInterface) *TorrentManager { func NewTorrentManager(config config.ConfigInterface, cache *expirable.LRU[string, string]) *TorrentManager {
handler := &TorrentManager{ handler := &TorrentManager{
token: config.GetToken(),
workerPool: make(chan bool, config.GetNumOfWorkers()),
config: config, config: config,
cache: cache,
workerPool: make(chan bool, config.GetNumOfWorkers()),
} }
// Initialize torrents for the first time // Initialize torrents for the first time
@@ -71,7 +73,7 @@ func NewTorrentManager(config config.ConfigInterface) *TorrentManager {
} }
func (t *TorrentManager) getChecksum() string { 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 { if err != nil {
log.Printf("Cannot get torrents: %v\n", err) log.Printf("Cannot get torrents: %v\n", err)
return t.checksum return t.checksum
@@ -86,7 +88,7 @@ func (t *TorrentManager) getChecksum() string {
func (t *TorrentManager) getAll() []Torrent { func (t *TorrentManager) getAll() []Torrent {
log.Println("Getting all torrents") 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 { if err != nil {
log.Printf("Cannot get torrents: %v\n", err) log.Printf("Cannot get torrents: %v\n", err)
return nil return nil
@@ -172,7 +174,7 @@ func (t *TorrentManager) getInfo(torrentID string) *Torrent {
return torrent return torrent
} }
log.Println("Getting info for", torrentID) log.Println("Getting info for", torrentID)
info, err := realdebrid.GetTorrentInfo(t.token, torrentID) info, err := realdebrid.GetTorrentInfo(t.config.GetToken(), torrentID)
if err != nil { if err != nil {
log.Printf("Cannot get info: %v\n", err) log.Printf("Cannot get info: %v\n", err)
return nil return nil
@@ -209,7 +211,7 @@ func (t *TorrentManager) getInfo(torrentID string) *Torrent {
defer func() { <-sem }() // Release semaphore defer func() { <-sem }() // Release semaphore
unrestrictFn := func() (*realdebrid.UnrestrictResponse, error) { unrestrictFn := func() (*realdebrid.UnrestrictResponse, error) {
return realdebrid.UnrestrictCheck(t.token, lnk) return realdebrid.UnrestrictCheck(t.config.GetToken(), lnk)
} }
resp := realdebrid.RetryUntilOk(unrestrictFn) resp := realdebrid.RetryUntilOk(unrestrictFn)
if resp != nil { if resp != nil {