package filesystem import ( "context" "encoding/json" "log/slog" "os" "strings" "time" ) const keyReadDir = "webdav:readdir:" func (c *CachedClient) ReadDir(path string) ([]os.FileInfo, error) { key := keyReadDir + path ctx := context.Background() // Try cache val, err := c.cache.Do(ctx, c.cache.B().Get().Key(key).Build()).ToString() if err == nil && val != "" { var cached []File if err := json.Unmarshal([]byte(val), &cached); err == nil { c.readDirHits.Add(1) c.hits.Add(1) infos := make([]os.FileInfo, len(cached)) for i, f := range cached { infos[i] = f } return infos, nil } } // Cache miss c.misses.Add(1) slog.Debug("cache miss", "key", key) infos, err := c.impl.ReadDir(path) if err != nil { return nil, err } // Serialize and cache cached := make([]File, 0, len(infos)) for _, info := range infos { cached = append(cached, ParseToFile(info)) } bytes, err := json.Marshal(cached) if err == nil { c.cache.Do(ctx, c.cache.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build()) } return infos, nil } func (c *CachedClient) revalidateReadDir(ctx context.Context) { startTime := time.Now() c.scanAndProcess(ctx, keyReadDir+"*", func(key string) error { path := strings.TrimPrefix(key, keyReadDir) infos, err := c.impl.ReadDir(path) if err != nil { c.cache.Do(ctx, c.cache.B().Del().Key(key).Build()) return err } // Serialize and cache cached := make([]File, 0, len(infos)) for _, info := range infos { cached = append(cached, ParseToFile(info)) } bytes, err := json.Marshal(cached) if err == nil { c.cache.Do(ctx, c.cache.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build()) } return nil }) slog.Debug("revalidation of readDir complete", "duration", time.Since(startTime)) }