Resolve race condition issues

This commit is contained in:
Ben Sarmiento
2023-11-04 14:13:24 +01:00
parent b2e957cb4c
commit 4136310622
8 changed files with 136 additions and 26 deletions

View File

@@ -16,33 +16,41 @@ import (
)
type TorrentManager struct {
requiredVersion string
torrents []Torrent
inProgress []string
checksum string
config config.ConfigInterface
cache *expirable.LRU[string, string]
workerPool chan bool
TorrentDirectoriesMap map[string][]string
processedTorrents map[string][]string
requiredVersion string
torrents []Torrent
inProgress []string
checksum string
config config.ConfigInterface
cache *expirable.LRU[string, string]
workerPool chan bool
directoryMap map[string][]string
processedTorrents map[string][]string
mu *sync.Mutex
}
// NewTorrentManager creates a new torrent manager
// it will fetch all torrents and their info in the background
// and store them in-memory
// and store them in-memory; it is called only once at startup
func NewTorrentManager(config config.ConfigInterface, cache *expirable.LRU[string, string]) *TorrentManager {
t := &TorrentManager{
requiredVersion: "28.10.2023",
config: config,
cache: cache,
workerPool: make(chan bool, config.GetNumOfWorkers()),
TorrentDirectoriesMap: make(map[string][]string),
processedTorrents: make(map[string][]string),
requiredVersion: "4.11.2023",
config: config,
cache: cache,
workerPool: make(chan bool, config.GetNumOfWorkers()),
directoryMap: make(map[string][]string),
processedTorrents: make(map[string][]string),
mu: &sync.Mutex{},
}
// Initialize torrents for the first time
log.Println("Initializing torrents")
t.mu.Lock()
log.Println("Fetching torrents")
t.torrents = t.getFreshListFromAPI()
t.checksum = t.getChecksum()
t.mu.Unlock()
log.Println("Finished fetching torrents")
// log.Println("First checksum", t.checksum)
var wg sync.WaitGroup
@@ -72,7 +80,7 @@ func NewTorrentManager(config config.ConfigInterface, cache *expirable.LRU[strin
func (t *TorrentManager) GetByDirectory(directory string) []Torrent {
var torrents []Torrent
for i := range t.torrents {
for _, dir := range t.TorrentDirectoriesMap[t.torrents[i].Name] {
for _, dir := range t.directoryMap[t.torrents[i].Name] {
if dir == directory {
torrents = append(torrents, t.torrents[i])
}
@@ -195,8 +203,11 @@ func (t *TorrentManager) startRefreshJob() {
wg.Wait()
// apply side effects
t.mu.Lock()
t.torrents = newTorrents
t.checksum = t.getChecksum()
t.mu.Unlock()
// log.Println("Checksum changed", t.checksum)
if t.config.EnableRepair() {
go t.repairAll(&wg)
@@ -223,6 +234,8 @@ func (t *TorrentManager) getFreshListFromAPI() []Torrent {
torrentV2 := Torrent{
Torrent: torrent,
SelectedFiles: nil,
ForRepair: false,
lock: &sync.Mutex{},
}
torrentsV2 = append(torrentsV2, torrentV2)
@@ -361,7 +374,7 @@ func (t *TorrentManager) mapToDirectories() {
if configV1.MeetsConditions(directory, t.torrents[i].ID, t.torrents[i].Name, filenames) {
found := false
// check if it is already mapped to this directory
for _, dir := range t.TorrentDirectoriesMap[t.torrents[i].Name] {
for _, dir := range t.directoryMap[t.torrents[i].Name] {
if dir == directory {
found = true
break // it is already mapped to this directory
@@ -369,12 +382,16 @@ func (t *TorrentManager) mapToDirectories() {
}
if !found {
counter[directory]++
t.TorrentDirectoriesMap[t.torrents[i].Name] = append(t.TorrentDirectoriesMap[t.torrents[i].Name], directory)
t.mu.Lock()
t.directoryMap[t.torrents[i].Name] = append(t.directoryMap[t.torrents[i].Name], directory)
t.mu.Unlock()
break // we found a directory for this torrent, so we can stop looking for more
}
}
}
t.mu.Lock()
t.processedTorrents[t.torrents[i].Name] = append(t.processedTorrents[t.torrents[i].Name], group)
t.mu.Unlock()
}
sum := 0
for _, count := range counter {
@@ -439,7 +456,6 @@ func (t *TorrentManager) readFromFile(torrentID string) *Torrent {
dataDecoder := gob.NewDecoder(file)
err = dataDecoder.Decode(&torrent)
if err != nil {
log.Fatalf("Failed decoding file: %s", err)
return nil
}
if torrent.Version != t.requiredVersion {