58 lines
1.6 KiB
Go
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
|
|
}
|