package internal import ( "encoding/gob" "encoding/json" "errors" "fmt" "os" "path/filepath" "strings" "time" "github.com/dominikbraun/graph" "github.com/patrickmn/go-cache" ) var Cache = cache.New(120*time.Minute, 0) var sharedLogger = TxtLogger() func SaveCacheToFiles(directory string, accountID string) error { err := os.MkdirAll(directory, 0755) if err != nil { return err } for key, item := range Cache.Items() { if accountID != "" && strings.Contains(key, accountID) { entry := cacheEntry{ Value: item.Object, Exp: item.Expiration, } jsonData, err := json.MarshalIndent(entry, "", " ") if err != nil { return err } filename := filepath.Join(directory, key+".json") err = os.WriteFile(filename, jsonData, 0644) if err != nil { return err } } } return nil } func LoadCacheFromFiles(directory string) error { _, err := os.Stat(directory) if os.IsNotExist(err) { // Directory doesn't exist, skip loading cache return nil } else if err != nil { return err } files, err := os.ReadDir(directory) if err != nil { return err } for _, file := range files { if file.IsDir() { continue } filename := filepath.Join(directory, file.Name()) jsonData, err := os.ReadFile(filename) if err != nil { return err } var entry cacheEntry err = json.Unmarshal(jsonData, &entry) if err != nil { return err } key := strings.TrimSuffix(file.Name(), ".json") Cache.Set(key, entry.Value, time.Duration(entry.Exp-time.Now().UnixNano())) } fmt.Println("Cache loaded from files.") return nil } type cacheEntry struct { Value interface{} Exp int64 } type CacheableAWSConfig struct { Region string //Credentials aws.CredentialsProvider //ConfigSources []interface{} } func SaveCacheToGobFiles(directory string, accountID string) error { err := os.MkdirAll(directory, 0755) if err != nil { return err } for key, item := range Cache.Items() { // only if the key contains the accountID if accountID != "" && strings.Contains(key, accountID) { entry := cacheEntry{ Value: item.Object, Exp: item.Expiration, } filename := filepath.Join(directory, key+".gob") file, err := os.Create(filename) if err != nil { return err } defer file.Close() encoder := gob.NewEncoder(file) err = encoder.Encode(entry) if err != nil { sharedLogger.Errorf("Could not encode the following key: %s", key) return err } // } } } return nil } var ErrDirectoryDoesNotExist = errors.New("directory does not exist") func LoadCacheFromGobFiles(directory string) error { _, err := os.Stat(directory) if os.IsNotExist(err) { // Directory doesn't exist, skip loading cache return ErrDirectoryDoesNotExist } else if err != nil { return err } files, err := os.ReadDir(directory) if err != nil { return err } for _, file := range files { if file.IsDir() { continue } // if the filetype is json, skip it if filepath.Ext(file.Name()) == ".json" { continue } filename := filepath.Join(directory, file.Name()) file, err := os.Open(filename) if err != nil { return err } defer file.Close() var entry cacheEntry decoder := gob.NewDecoder(file) err = decoder.Decode(&entry) if err != nil { sharedLogger.Errorf("Could not decode the following file: %s", filename) continue } // the key should remove the directory and the .json suffix from the filename and also trim the first slash key := strings.TrimSuffix(strings.TrimPrefix(filename, directory), ".gob")[1:] Cache.Set(key, entry.Value, time.Duration(entry.Exp-time.Now().UnixNano())) } //fmt.Println("Cache loaded from files.") return nil } func SaveGraphToGob[K comparable, T any](directory string, name string, g *graph.Graph[K, T]) error { err := os.MkdirAll(directory, 0755) if err != nil { return err } filename := filepath.Join(directory, name+".gob") file, err := os.Create(filename) if err != nil { return err } defer file.Close() encoder := gob.NewEncoder(file) err = encoder.Encode(g) if err != nil { sharedLogger.Errorf("Could not encode the following graph: %s", name) return err } return nil }