diff --git a/main.go b/main.go index eb8af3e..dab2921 100644 --- a/main.go +++ b/main.go @@ -31,14 +31,15 @@ type HTTPResponseJSON struct { // Caches data about available ROMs in memory so we don't need to reference the filesystem for each request type ROMCache struct { - ROMs []LineageOSROM - Cached map[string]bool // to quickly lookup if a file is already cached - sync.Mutex // We have multiple goroutines that may be accessing this data simultaneously, so we much lock / unlock it to prevent race conditions + ROMs []LineageOSROM `json:"roms"` + Cached map[string]bool `json:"-"` // to quickly lookup if a file is already cached + sync.Mutex `json:"-"` // We have multiple goroutines that may be accessing this data simultaneously, so we much lock / unlock it to prevent race conditions } const ( romDirectory = "public" // directory where ROMs are available for download buildOutDirectory = "out" // directory from build system containing artifacts which we can move to romDirectory + cacheFile = "public/romcache.json" ) var ( // evil global variable @@ -46,8 +47,25 @@ var ( // evil global variable ) func init() { + // intialize and load ROMCache from file - so we don't have to rehash all the big files again romCache = ROMCache{} romCache.Cached = make(map[string]bool) + romCacheJson, err := os.ReadFile(cacheFile) + if err != nil { + if err != os.ErrNotExist { // don't care if it doesn't exist, just skip it + log.Printf("failed to read romCache file : %v", err) + } + } else { // if opening the file's successful, then load the contents + err = json.Unmarshal(romCacheJson, &romCache) + if err != nil { + log.Printf("failed to unmarshal romCacheJson to romCache struct: %v", err) + } + } + + for _, rom := range romCache.ROMs { + romCache.Cached[rom.ID] = true + log.Printf("loaded cached file: %s", rom.Filename) + } // Check if any new build artifacts and preload the romCache moveBuildArtifacts() @@ -132,6 +150,26 @@ func updateROMCache() { romCache.Unlock() }(files[i]) } + + // save file to disk for next startup so we don't have to rehash all the files again + romCache.Lock() + romCacheJson, err := json.Marshal(romCache) + romCache.Unlock() + if err != nil { + log.Printf("failed to marshal romCache to json: %v", err) + return + } + + err = os.WriteFile(cacheFile, romCacheJson, 0644) + if err != nil { + log.Printf("failed to write '%s' file: %v", cacheFile, err) + log.Printf("attempting to remove '%s' to ensure integrity during next program startup...", cacheFile) + err = os.Remove(cacheFile) + if err != nil { + log.Printf("failed to remove file '%s': %v", cacheFile, err) + } + return + } } // returns true if new builds were moved