67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package filesystem
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"log/slog"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func (c *CachedClient) Stat(path string) (info os.FileInfo, err error) {
|
|
key := keyStat + 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 f File
|
|
if err := json.Unmarshal([]byte(val), &f); err == nil {
|
|
c.hits.Add(1)
|
|
|
|
return f, nil
|
|
}
|
|
}
|
|
|
|
// Cache miss
|
|
c.misses.Add(1)
|
|
slog.Debug("cache miss", "key", key)
|
|
fileInfo, err := c.impl.Stat(path)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// Serialize and cache
|
|
// Type assert to ensure we capture ContentType and Path
|
|
info = ParseToFile(fileInfo)
|
|
|
|
bytes, err := json.Marshal(info)
|
|
if err == nil {
|
|
c.cache.Do(ctx, c.cache.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build())
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (c *CachedClient) revalidateStat(ctx context.Context) {
|
|
startTime := time.Now()
|
|
c.scanAndProcess(ctx, keyStat+"*", func(key string) error {
|
|
path := strings.TrimPrefix(key, keyStat)
|
|
info, err := c.impl.Stat(path)
|
|
if err != nil {
|
|
c.cache.Do(ctx, c.cache.B().Del().Key(key).Build())
|
|
return err
|
|
}
|
|
|
|
// Serialize and cache
|
|
f := ParseToFile(info)
|
|
bytes, err := json.Marshal(f)
|
|
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 Stat complete", "duration", time.Since(startTime))
|
|
}
|