chore: custom error

This commit is contained in:
2026-03-02 22:38:28 +01:00
parent 6c1387c1cd
commit 2491d21963
19 changed files with 363 additions and 60 deletions
+5 -5
View File
@@ -14,7 +14,7 @@ const keyStat = "webdav:stat:"
// CachedClient wraps a FileSystem implementation with Valkey caching.
type CachedClient struct {
impl FS
client valkey.Client
cache valkey.Client
ttl time.Duration
hits atomic.Int64
misses atomic.Int64
@@ -25,9 +25,9 @@ type CachedClient struct {
// NewCachedClient creates a new CachedClient.
func NewCachedClient(impl FS, client valkey.Client, refreshtime time.Duration) *CachedClient {
c := &CachedClient{
impl: impl,
client: client,
ttl: refreshtime * 5,
impl: impl,
cache: client,
ttl: refreshtime * 5,
}
go func() {
@@ -50,7 +50,7 @@ func (c *CachedClient) revalidate(ctx context.Context) {
func (c *CachedClient) scanAndProcess(ctx context.Context, match string, process func(key string) error) {
cursor := uint64(0)
for {
res, err := c.client.Do(ctx, c.client.B().Scan().Cursor(cursor).Match(match).Build()).AsScanEntry()
res, err := c.cache.Do(ctx, c.cache.B().Scan().Cursor(cursor).Match(match).Build()).AsScanEntry()
if err != nil {
slog.Error("scan failed", "match", match, "err", err)
return
+7 -7
View File
@@ -22,7 +22,7 @@ func (c *CachedClient) Read(path string) ([]byte, error) {
ctx := context.Background()
// Try cache
cached, err := c.client.Do(ctx, c.client.B().Get().Key(key).Build()).AsBytes()
cached, err := c.cache.Do(ctx, c.cache.B().Get().Key(key).Build()).AsBytes()
if err == nil && len(cached) > 0 {
c.readHits.Add(1)
c.hits.Add(1)
@@ -58,7 +58,7 @@ func (c *CachedClient) Read(path string) ([]byte, error) {
}
// Cache
c.client.Do(ctx, c.client.B().Set().Key(key).Value(valkey.BinaryString(cached)).Ex(c.ttl).Build())
c.cache.Do(ctx, c.cache.B().Set().Key(key).Value(valkey.BinaryString(cached)).Ex(c.ttl).Build())
return data, nil
}
@@ -67,7 +67,7 @@ func (c *CachedClient) revalidateRead(ctx context.Context) {
startTime := time.Now()
c.scanAndProcess(ctx, keyRead+"*", func(key string) error {
path := strings.TrimPrefix(key, keyRead)
cached, err := c.client.Do(ctx, c.client.B().Get().Key(key).Build()).AsBytes()
cached, err := c.cache.Do(ctx, c.cache.B().Get().Key(key).Build()).AsBytes()
if err != nil {
// Key might be gone or error fetching
return nil
@@ -76,13 +76,13 @@ func (c *CachedClient) revalidateRead(ctx context.Context) {
var cachedFile readFile
err = json.Unmarshal(cached, &cachedFile)
if err != nil {
c.client.Do(ctx, c.client.B().Del().Key(key).Build())
c.cache.Do(ctx, c.cache.B().Del().Key(key).Build())
return err
}
info, err := c.impl.Stat(path)
if err != nil {
c.client.Do(ctx, c.client.B().Del().Key(key).Build())
c.cache.Do(ctx, c.cache.B().Del().Key(key).Build())
return nil
}
@@ -99,9 +99,9 @@ func (c *CachedClient) revalidateRead(ctx context.Context) {
return err
}
c.client.Do(ctx, c.client.B().Set().Key(key).Value(valkey.BinaryString(newCached)).Ex(c.ttl).Build())
c.cache.Do(ctx, c.cache.B().Set().Key(key).Value(valkey.BinaryString(newCached)).Ex(c.ttl).Build())
} else {
c.client.Do(ctx, c.client.B().Expire().Key(key).Seconds(int64(c.ttl/time.Second)).Build())
c.cache.Do(ctx, c.cache.B().Expire().Key(key).Seconds(int64(c.ttl/time.Second)).Build())
}
return nil
})
+4 -4
View File
@@ -16,7 +16,7 @@ func (c *CachedClient) ReadDir(path string) ([]os.FileInfo, error) {
ctx := context.Background()
// Try cache
val, err := c.client.Do(ctx, c.client.B().Get().Key(key).Build()).ToString()
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 {
@@ -47,7 +47,7 @@ func (c *CachedClient) ReadDir(path string) ([]os.FileInfo, error) {
bytes, err := json.Marshal(cached)
if err == nil {
c.client.Do(ctx, c.client.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build())
c.cache.Do(ctx, c.cache.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build())
}
return infos, nil
@@ -59,7 +59,7 @@ func (c *CachedClient) revalidateReadDir(ctx context.Context) {
path := strings.TrimPrefix(key, keyReadDir)
infos, err := c.impl.ReadDir(path)
if err != nil {
c.client.Do(ctx, c.client.B().Del().Key(key).Build())
c.cache.Do(ctx, c.cache.B().Del().Key(key).Build())
return err
}
@@ -71,7 +71,7 @@ func (c *CachedClient) revalidateReadDir(ctx context.Context) {
bytes, err := json.Marshal(cached)
if err == nil {
c.client.Do(ctx, c.client.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build())
c.cache.Do(ctx, c.cache.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build())
}
return nil
})
+4 -4
View File
@@ -14,7 +14,7 @@ func (c *CachedClient) Stat(path string) (info os.FileInfo, err error) {
ctx := context.Background()
// Try cache
val, err := c.client.Do(ctx, c.client.B().Get().Key(key).Build()).ToString()
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 {
@@ -39,7 +39,7 @@ func (c *CachedClient) Stat(path string) (info os.FileInfo, err error) {
bytes, err := json.Marshal(info)
if err == nil {
c.client.Do(ctx, c.client.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build())
c.cache.Do(ctx, c.cache.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build())
}
return
@@ -51,7 +51,7 @@ func (c *CachedClient) revalidateStat(ctx context.Context) {
path := strings.TrimPrefix(key, keyStat)
info, err := c.impl.Stat(path)
if err != nil {
c.client.Do(ctx, c.client.B().Del().Key(key).Build())
c.cache.Do(ctx, c.cache.B().Del().Key(key).Build())
return err
}
@@ -59,7 +59,7 @@ func (c *CachedClient) revalidateStat(ctx context.Context) {
f := ParseToFile(info)
bytes, err := json.Marshal(f)
if err == nil {
c.client.Do(ctx, c.client.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build())
c.cache.Do(ctx, c.cache.B().Set().Key(key).Value(string(bytes)).Ex(c.ttl).Build())
}
return nil
})