Keep application/octet-stream out of memory for variants (closes #70)
check / check (push) Successful in 3m30s
check / check (push) Successful in 3m30s
VariantStorage.LoadWithMeta now returns an empty content type when the .meta file is missing or unreadable, and GetVariant serves application/octet-stream in that case without keeping it in memory. Memory now only ever holds a content type read from a .meta file or passed to StoreVariant, so a read that ran before a store wrote the .meta file can no longer leave the wrong type in memory, however it interleaves with the store, other reads and eviction. Model: opus-5-5
This commit is contained in:
@@ -184,7 +184,9 @@ func (c *Cache) Lookup(ctx context.Context, req *ImageRequest) (*LookupResult, e
|
||||
|
||||
// GetVariant returns a reader, size, and content type for a cached
|
||||
// variant. The content type comes from metaCache, or else from the
|
||||
// variant's .meta file and is then kept in metaCache.
|
||||
// variant's .meta file and is then kept in metaCache. A variant with
|
||||
// no .meta file is served as application/octet-stream, which is not
|
||||
// kept.
|
||||
func (c *Cache) GetVariant(cacheKey VariantKey) (io.ReadCloser, int64, string, error) {
|
||||
if c.disabled {
|
||||
return nil, 0, "", ErrNotFound
|
||||
@@ -521,9 +523,11 @@ func (c *Cache) IncrementTransformCount(ctx context.Context) {
|
||||
// loadVariantWithMeta is GetVariant for a variant metaCache does not
|
||||
// hold: it reads the content type from the variant's .meta file and
|
||||
// keeps it in metaCache, unless a StoreVariant has put one there
|
||||
// meanwhile. The stored one wins, since this read may have found the
|
||||
// variant file before the store wrote the .meta file, and so got
|
||||
// application/octet-stream.
|
||||
// meanwhile, as the store's is newer. A read that finds no .meta file,
|
||||
// as one can between a store's writing of the variant file and of its
|
||||
// .meta file, serves application/octet-stream and keeps nothing, so
|
||||
// metaCache only ever holds a type read from a .meta file or passed to
|
||||
// StoreVariant.
|
||||
func (c *Cache) loadVariantWithMeta(
|
||||
cacheKey VariantKey,
|
||||
) (io.ReadCloser, int64, string, error) {
|
||||
@@ -532,6 +536,10 @@ func (c *Cache) loadVariantWithMeta(
|
||||
return nil, 0, "", err
|
||||
}
|
||||
|
||||
if contentType == "" {
|
||||
return reader, size, fallbackContentType, nil
|
||||
}
|
||||
|
||||
c.metaCache.ContainsOrAdd(cacheKey, contentType)
|
||||
|
||||
return reader, size, contentType, nil
|
||||
|
||||
@@ -39,8 +39,8 @@ const tempFilePrefix = ".tmp-"
|
||||
// to each variant file.
|
||||
const variantMetaSuffix = ".meta"
|
||||
|
||||
// fallbackContentType is recorded when a reconciled variant file has
|
||||
// no readable .meta sidecar.
|
||||
// fallbackContentType is the content type given to a variant file that
|
||||
// has no readable .meta sidecar, when it is served or reconciled.
|
||||
const fallbackContentType = "application/octet-stream"
|
||||
|
||||
// UsageBytes returns the total number of bytes of cache content
|
||||
|
||||
@@ -531,7 +531,8 @@ func (s *VariantStorage) LoadWithSize(key VariantKey) (io.ReadCloser, int64, err
|
||||
}
|
||||
|
||||
// LoadWithMeta returns a reader, size, and content type for the content at
|
||||
// the given key.
|
||||
// the given key. The content type is read from the .meta file, and is
|
||||
// empty when that file is missing or unreadable.
|
||||
func (s *VariantStorage) LoadWithMeta(
|
||||
key VariantKey,
|
||||
) (io.ReadCloser, int64, string, error) {
|
||||
@@ -540,8 +541,8 @@ func (s *VariantStorage) LoadWithMeta(
|
||||
return nil, 0, "", err
|
||||
}
|
||||
|
||||
// Load metadata for content type
|
||||
contentType := "application/octet-stream" // fallback
|
||||
var contentType string
|
||||
|
||||
metaPath := s.keyToPath(key) + ".meta"
|
||||
|
||||
metaData, err := os.ReadFile(metaPath) //nolint:gosec // path derived from cache key
|
||||
|
||||
Reference in New Issue
Block a user