Files
any-hub/internal/cache/writer.go
2025-11-15 21:15:12 +08:00

58 lines
1.6 KiB
Go

package cache
import (
"context"
"errors"
"io"
"time"
"github.com/any-hub/any-hub/internal/hubmodule"
)
// ErrStoreUnavailable 表示当前模块未注入缓存存储实例。
var ErrStoreUnavailable = errors.New("cache store unavailable")
// StrategyWriter 注入模块的缓存策略,提供 TTL 决策与写入封装。
type StrategyWriter struct {
store Store
strategy hubmodule.CacheStrategyProfile
now func() time.Time
}
// NewStrategyWriter 构造策略感知的写入器,默认使用 time.Now 作为时钟。
func NewStrategyWriter(store Store, strategy hubmodule.CacheStrategyProfile) StrategyWriter {
return StrategyWriter{
store: store,
strategy: strategy,
now: time.Now,
}
}
// Enabled 返回当前是否具备缓存写入能力。
func (w StrategyWriter) Enabled() bool {
return w.store != nil
}
// Put 写入缓存正文,并保持与 Store 相同的语义。
func (w StrategyWriter) Put(ctx context.Context, locator Locator, body io.Reader, opts PutOptions) (*Entry, error) {
if w.store == nil {
return nil, ErrStoreUnavailable
}
return w.store.Put(ctx, locator, body, opts)
}
// ShouldBypassValidation 根据策略 TTL 判断是否可以直接复用缓存,避免重复 HEAD。
func (w StrategyWriter) ShouldBypassValidation(entry Entry) bool {
ttl := w.strategy.TTLHint
if ttl <= 0 {
return false
}
expireAt := entry.ModTime.Add(ttl)
return w.now().Before(expireAt)
}
// SupportsValidation 返回当前策略是否允许通过 HEAD/Etag 等方式再验证。
func (w StrategyWriter) SupportsValidation() bool {
return w.strategy.ValidationMode != hubmodule.ValidationModeNever
}