Fix hot cache to include ContentType and SizeBytes
Hot cache entries now store all data needed to serve a cache hit without any database access: - OutputHash (for file lookup) - ContentType (for Content-Type header) - SizeBytes (for Content-Length header) Previously hot cache only stored OutputHash, causing empty Content-Type headers on cached WebP responses.
This commit is contained in:
@@ -30,6 +30,13 @@ type CacheConfig struct {
|
||||
HotCacheEnabled bool
|
||||
}
|
||||
|
||||
// hotCacheEntry stores all data needed to serve a cache hit without DB access.
|
||||
type hotCacheEntry struct {
|
||||
OutputHash string
|
||||
ContentType string
|
||||
SizeBytes int64
|
||||
}
|
||||
|
||||
// Cache implements the caching layer for the image proxy.
|
||||
type Cache struct {
|
||||
db *sql.DB
|
||||
@@ -37,7 +44,7 @@ type Cache struct {
|
||||
dstContent *ContentStorage
|
||||
srcMetadata *MetadataStorage
|
||||
config CacheConfig
|
||||
hotCache map[string]string // cache_key -> output_hash
|
||||
hotCache map[string]hotCacheEntry // cache_key -> entry
|
||||
hotCacheMu sync.RWMutex
|
||||
hotCacheEnabled bool
|
||||
}
|
||||
@@ -69,7 +76,7 @@ func NewCache(db *sql.DB, config CacheConfig) (*Cache, error) {
|
||||
}
|
||||
|
||||
if config.HotCacheEnabled && config.HotCacheSize > 0 {
|
||||
c.hotCache = make(map[string]string, config.HotCacheSize)
|
||||
c.hotCache = make(map[string]hotCacheEntry, config.HotCacheSize)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
@@ -80,6 +87,7 @@ type LookupResult struct {
|
||||
Hit bool
|
||||
OutputHash string
|
||||
ContentType string
|
||||
SizeBytes int64
|
||||
CacheStatus CacheStatus
|
||||
}
|
||||
|
||||
@@ -90,13 +98,15 @@ func (c *Cache) Lookup(ctx context.Context, req *ImageRequest) (*LookupResult, e
|
||||
// Check hot cache first
|
||||
if c.hotCacheEnabled {
|
||||
c.hotCacheMu.RLock()
|
||||
outputHash, ok := c.hotCache[cacheKey]
|
||||
entry, ok := c.hotCache[cacheKey]
|
||||
c.hotCacheMu.RUnlock()
|
||||
|
||||
if ok && c.dstContent.Exists(outputHash) {
|
||||
if ok && c.dstContent.Exists(entry.OutputHash) {
|
||||
return &LookupResult{
|
||||
Hit: true,
|
||||
OutputHash: outputHash,
|
||||
OutputHash: entry.OutputHash,
|
||||
ContentType: entry.ContentType,
|
||||
SizeBytes: entry.SizeBytes,
|
||||
CacheStatus: CacheHit,
|
||||
}, nil
|
||||
}
|
||||
@@ -114,14 +124,15 @@ func (c *Cache) Lookup(ctx context.Context, req *ImageRequest) (*LookupResult, e
|
||||
|
||||
// Check database
|
||||
var outputHash, contentType string
|
||||
var sizeBytes int64
|
||||
var fetchedAt time.Time
|
||||
|
||||
err = c.db.QueryRowContext(ctx, `
|
||||
SELECT rc.output_hash, oc.content_type, rc.fetched_at
|
||||
SELECT rc.output_hash, oc.content_type, oc.size_bytes, rc.fetched_at
|
||||
FROM request_cache rc
|
||||
JOIN output_content oc ON rc.output_hash = oc.content_hash
|
||||
WHERE rc.cache_key = ?
|
||||
`, cacheKey).Scan(&outputHash, &contentType, &fetchedAt)
|
||||
`, cacheKey).Scan(&outputHash, &contentType, &sizeBytes, &fetchedAt)
|
||||
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return &LookupResult{Hit: false, CacheStatus: CacheMiss}, nil
|
||||
@@ -144,7 +155,11 @@ func (c *Cache) Lookup(ctx context.Context, req *ImageRequest) (*LookupResult, e
|
||||
// Update hot cache
|
||||
if c.hotCacheEnabled {
|
||||
c.hotCacheMu.Lock()
|
||||
c.hotCache[cacheKey] = outputHash
|
||||
c.hotCache[cacheKey] = hotCacheEntry{
|
||||
OutputHash: outputHash,
|
||||
ContentType: contentType,
|
||||
SizeBytes: sizeBytes,
|
||||
}
|
||||
c.hotCacheMu.Unlock()
|
||||
}
|
||||
|
||||
@@ -159,6 +174,7 @@ func (c *Cache) Lookup(ctx context.Context, req *ImageRequest) (*LookupResult, e
|
||||
Hit: true,
|
||||
OutputHash: outputHash,
|
||||
ContentType: contentType,
|
||||
SizeBytes: sizeBytes,
|
||||
CacheStatus: CacheHit,
|
||||
}, nil
|
||||
}
|
||||
@@ -277,7 +293,11 @@ func (c *Cache) StoreOutput(
|
||||
// Update hot cache
|
||||
if c.hotCacheEnabled {
|
||||
c.hotCacheMu.Lock()
|
||||
c.hotCache[cacheKey] = outputHash
|
||||
c.hotCache[cacheKey] = hotCacheEntry{
|
||||
OutputHash: outputHash,
|
||||
ContentType: contentType,
|
||||
SizeBytes: size,
|
||||
}
|
||||
c.hotCacheMu.Unlock()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user