80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
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)
|
|
slog.Debug("cache hit", "key", key)
|
|
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))
|
|
}
|