cleanup torrent cache
This commit is contained in:
@@ -552,6 +552,10 @@ func (c *Cache) GetTorrents() map[string]CachedTorrent {
|
||||
return c.torrents.getAll()
|
||||
}
|
||||
|
||||
func (c *Cache) TotalTorrents() int {
|
||||
return c.torrents.getAllCount()
|
||||
}
|
||||
|
||||
func (c *Cache) GetTorrentByName(name string) *CachedTorrent {
|
||||
if torrent, ok := c.torrents.getByName(name); ok {
|
||||
return &torrent
|
||||
|
||||
@@ -137,10 +137,10 @@ func (c *Cache) refreshRclone() error {
|
||||
}
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
Timeout: 60 * time.Second,
|
||||
Transport: &http.Transport{
|
||||
MaxIdleConns: 10,
|
||||
IdleConnTimeout: 30 * time.Second,
|
||||
IdleConnTimeout: 60 * time.Second,
|
||||
DisableCompression: false,
|
||||
MaxIdleConnsPerHost: 5,
|
||||
},
|
||||
|
||||
@@ -40,13 +40,22 @@ type directoryFilter struct {
|
||||
ageThreshold time.Duration // only for last_added
|
||||
}
|
||||
|
||||
type torrents struct {
|
||||
sync.RWMutex
|
||||
byID map[string]CachedTorrent
|
||||
byName map[string]CachedTorrent
|
||||
}
|
||||
|
||||
type folders struct {
|
||||
sync.RWMutex
|
||||
listing map[string][]os.FileInfo // folder name to file listing
|
||||
}
|
||||
|
||||
type torrentCache struct {
|
||||
mu sync.Mutex
|
||||
byID map[string]CachedTorrent
|
||||
byName map[string]CachedTorrent
|
||||
torrents torrents
|
||||
|
||||
listing atomic.Value
|
||||
folderListing map[string][]os.FileInfo
|
||||
folderListingMu sync.RWMutex
|
||||
folders folders
|
||||
directoriesFilters map[string][]directoryFilter
|
||||
sortNeeded atomic.Bool
|
||||
}
|
||||
@@ -62,9 +71,13 @@ type sortableFile struct {
|
||||
func newTorrentCache(dirFilters map[string][]directoryFilter) *torrentCache {
|
||||
|
||||
tc := &torrentCache{
|
||||
byID: make(map[string]CachedTorrent),
|
||||
byName: make(map[string]CachedTorrent),
|
||||
folderListing: make(map[string][]os.FileInfo),
|
||||
torrents: torrents{
|
||||
byID: make(map[string]CachedTorrent),
|
||||
byName: make(map[string]CachedTorrent),
|
||||
},
|
||||
folders: folders{
|
||||
listing: make(map[string][]os.FileInfo),
|
||||
},
|
||||
directoriesFilters: dirFilters,
|
||||
}
|
||||
|
||||
@@ -74,41 +87,42 @@ func newTorrentCache(dirFilters map[string][]directoryFilter) *torrentCache {
|
||||
}
|
||||
|
||||
func (tc *torrentCache) reset() {
|
||||
tc.mu.Lock()
|
||||
tc.byID = make(map[string]CachedTorrent)
|
||||
tc.byName = make(map[string]CachedTorrent)
|
||||
tc.mu.Unlock()
|
||||
tc.torrents.Lock()
|
||||
tc.torrents.byID = make(map[string]CachedTorrent)
|
||||
tc.torrents.byName = make(map[string]CachedTorrent)
|
||||
tc.torrents.Unlock()
|
||||
|
||||
// reset the sorted listing
|
||||
tc.sortNeeded.Store(false)
|
||||
tc.listing.Store(make([]os.FileInfo, 0))
|
||||
|
||||
// reset any per-folder views
|
||||
tc.folderListingMu.Lock()
|
||||
tc.folderListing = make(map[string][]os.FileInfo)
|
||||
tc.folderListingMu.Unlock()
|
||||
tc.folders.Lock()
|
||||
tc.folders.listing = make(map[string][]os.FileInfo)
|
||||
tc.folders.Unlock()
|
||||
}
|
||||
|
||||
func (tc *torrentCache) getByID(id string) (CachedTorrent, bool) {
|
||||
tc.mu.Lock()
|
||||
defer tc.mu.Unlock()
|
||||
torrent, exists := tc.byID[id]
|
||||
tc.torrents.RLock()
|
||||
defer tc.torrents.RUnlock()
|
||||
torrent, exists := tc.torrents.byID[id]
|
||||
return torrent, exists
|
||||
}
|
||||
|
||||
func (tc *torrentCache) getByName(name string) (CachedTorrent, bool) {
|
||||
tc.mu.Lock()
|
||||
defer tc.mu.Unlock()
|
||||
torrent, exists := tc.byName[name]
|
||||
tc.torrents.RLock()
|
||||
defer tc.torrents.RUnlock()
|
||||
torrent, exists := tc.torrents.byName[name]
|
||||
return torrent, exists
|
||||
}
|
||||
|
||||
func (tc *torrentCache) set(name string, torrent, newTorrent CachedTorrent) {
|
||||
tc.mu.Lock()
|
||||
tc.torrents.Lock()
|
||||
// Set the id first
|
||||
tc.byID[newTorrent.Id] = torrent // This is the unadulterated torrent
|
||||
tc.byName[name] = newTorrent // This is likely the modified torrent
|
||||
tc.mu.Unlock()
|
||||
|
||||
tc.torrents.byName[name] = torrent
|
||||
tc.torrents.byID[torrent.Id] = torrent // This is the unadulterated torrent
|
||||
tc.torrents.Unlock()
|
||||
tc.sortNeeded.Store(true)
|
||||
}
|
||||
|
||||
@@ -124,12 +138,12 @@ func (tc *torrentCache) getListing() []os.FileInfo {
|
||||
}
|
||||
|
||||
func (tc *torrentCache) getFolderListing(folderName string) []os.FileInfo {
|
||||
tc.folderListingMu.RLock()
|
||||
defer tc.folderListingMu.RUnlock()
|
||||
tc.folders.RLock()
|
||||
defer tc.folders.RUnlock()
|
||||
if folderName == "" {
|
||||
return tc.getListing()
|
||||
}
|
||||
if folder, ok := tc.folderListing[folderName]; ok {
|
||||
if folder, ok := tc.folders.listing[folderName]; ok {
|
||||
return folder
|
||||
}
|
||||
// If folder not found, return empty slice
|
||||
@@ -138,13 +152,13 @@ func (tc *torrentCache) getFolderListing(folderName string) []os.FileInfo {
|
||||
|
||||
func (tc *torrentCache) refreshListing() {
|
||||
|
||||
tc.mu.Lock()
|
||||
all := make([]sortableFile, 0, len(tc.byName))
|
||||
for name, t := range tc.byName {
|
||||
tc.torrents.RLock()
|
||||
all := make([]sortableFile, 0, len(tc.torrents.byName))
|
||||
for name, t := range tc.torrents.byName {
|
||||
all = append(all, sortableFile{t.Id, name, t.AddedOn, t.Bytes, t.Bad})
|
||||
}
|
||||
tc.sortNeeded.Store(false)
|
||||
tc.mu.Unlock()
|
||||
tc.torrents.RUnlock()
|
||||
|
||||
sort.Slice(all, func(i, j int) bool {
|
||||
if all[i].name != all[j].name {
|
||||
@@ -181,13 +195,13 @@ func (tc *torrentCache) refreshListing() {
|
||||
})
|
||||
}
|
||||
}
|
||||
tc.folderListingMu.Lock()
|
||||
tc.folders.Lock()
|
||||
if len(listing) > 0 {
|
||||
tc.folderListing["__bad__"] = listing
|
||||
tc.folders.listing["__bad__"] = listing
|
||||
} else {
|
||||
delete(tc.folderListing, "__bad__")
|
||||
delete(tc.folders.listing, "__bad__")
|
||||
}
|
||||
tc.folderListingMu.Unlock()
|
||||
tc.folders.Unlock()
|
||||
}()
|
||||
wg.Done()
|
||||
|
||||
@@ -207,13 +221,13 @@ func (tc *torrentCache) refreshListing() {
|
||||
}
|
||||
}
|
||||
|
||||
tc.folderListingMu.Lock()
|
||||
tc.folders.Lock()
|
||||
if len(matched) > 0 {
|
||||
tc.folderListing[dir] = matched
|
||||
tc.folders.listing[dir] = matched
|
||||
} else {
|
||||
delete(tc.folderListing, dir)
|
||||
delete(tc.folders.listing, dir)
|
||||
}
|
||||
tc.folderListingMu.Unlock()
|
||||
tc.folders.Unlock()
|
||||
}(dir, filters)
|
||||
}
|
||||
|
||||
@@ -264,35 +278,41 @@ func (tc *torrentCache) torrentMatchDirectory(filters []directoryFilter, file so
|
||||
}
|
||||
|
||||
func (tc *torrentCache) getAll() map[string]CachedTorrent {
|
||||
tc.mu.Lock()
|
||||
defer tc.mu.Unlock()
|
||||
result := make(map[string]CachedTorrent)
|
||||
for name, torrent := range tc.byID {
|
||||
tc.torrents.RLock()
|
||||
defer tc.torrents.RUnlock()
|
||||
result := make(map[string]CachedTorrent, len(tc.torrents.byID))
|
||||
for name, torrent := range tc.torrents.byID {
|
||||
result[name] = torrent
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (tc *torrentCache) getAllCount() int {
|
||||
tc.torrents.RLock()
|
||||
defer tc.torrents.RUnlock()
|
||||
return len(tc.torrents.byID)
|
||||
}
|
||||
|
||||
func (tc *torrentCache) getIdMaps() map[string]struct{} {
|
||||
tc.mu.Lock()
|
||||
defer tc.mu.Unlock()
|
||||
res := make(map[string]struct{}, len(tc.byID))
|
||||
for id := range tc.byID {
|
||||
tc.torrents.RLock()
|
||||
defer tc.torrents.RUnlock()
|
||||
res := make(map[string]struct{}, len(tc.torrents.byID))
|
||||
for id := range tc.torrents.byID {
|
||||
res[id] = struct{}{}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (tc *torrentCache) removeId(id string) {
|
||||
tc.mu.Lock()
|
||||
defer tc.mu.Unlock()
|
||||
delete(tc.byID, id)
|
||||
tc.torrents.Lock()
|
||||
defer tc.torrents.Unlock()
|
||||
delete(tc.torrents.byID, id)
|
||||
tc.sortNeeded.Store(true)
|
||||
}
|
||||
|
||||
func (tc *torrentCache) remove(name string) {
|
||||
tc.mu.Lock()
|
||||
defer tc.mu.Unlock()
|
||||
delete(tc.byName, name)
|
||||
tc.torrents.Lock()
|
||||
defer tc.torrents.Unlock()
|
||||
delete(tc.torrents.byName, name)
|
||||
tc.sortNeeded.Store(true)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user