Files
MeBox/internal/service/cloud115/url_cache.go
T
truewhile 0aff87c69d 优化
优化
2026-08-24 17:00:18 +08:00

75 lines
1.9 KiB
Go

// 下载直链进程级缓存。
//
// 115 的 /open/ufile/downurl 换取结果在一段时间内有效,且换取请求是
// WAF 风控重点关注的密集接口。缓存按 pickcode 存直链、避免对同一文件
// 反复换取;下载失败(http 403/404 等)时由调用方主动清除对应条目,
// 下一轮重试会重新换取链接。
package cloud115
import (
"sync"
"time"
)
// downloadURLCacheTTL 直链缓存时长。115 直链一般有效 1 小时左右,
// 取 45 分钟留出余量。QMediaSync 同类缓存使用 50 分钟。
const downloadURLCacheTTL = 45 * time.Minute
// maxCachedURLs 超过该数量时顺带清理过期条目,防止 map 无限膨胀。
const maxCachedURLs = 10000
type urlCacheEntry struct {
url string
expiresAt time.Time
}
var (
urlCacheMu sync.Mutex
urlCache = map[string]urlCacheEntry{}
)
// GetDownloadURLCache 返回未过期的缓存直链;不存在或已过期返回空串。
func GetDownloadURLCache(pickCode string) string {
if pickCode == "" {
return ""
}
urlCacheMu.Lock()
defer urlCacheMu.Unlock()
entry, ok := urlCache[pickCode]
if !ok || time.Now().After(entry.expiresAt) {
if ok {
delete(urlCache, pickCode)
}
return ""
}
return entry.url
}
// SetDownloadURLCache 写入直链缓存。
func SetDownloadURLCache(pickCode, url string) {
if pickCode == "" || url == "" {
return
}
urlCacheMu.Lock()
defer urlCacheMu.Unlock()
if len(urlCache) >= maxCachedURLs {
now := time.Now()
for k, e := range urlCache {
if now.After(e.expiresAt) {
delete(urlCache, k)
}
}
}
urlCache[pickCode] = urlCacheEntry{url: url, expiresAt: time.Now().Add(downloadURLCacheTTL)}
}
// ClearDownloadURLCache 删除指定 pickcode 的缓存(下载得到非 2xx 时调用)。
func ClearDownloadURLCache(pickCode string) {
if pickCode == "" {
return
}
urlCacheMu.Lock()
defer urlCacheMu.Unlock()
delete(urlCache, pickCode)
}