Skip to content

Fix ImageCache limit races and ImagePipeline.Cache key and option handling - #1027

Open
kean wants to merge 5 commits into
mainfrom
fix/cache-limits-keys-contains
Open

kean wants to merge 5 commits into
mainfrom
fix/cache-limits-keys-contains

Conversation

@kean

@kean kean commented Sep 26, 2026

Copy link
Copy Markdown
Owner

Four small caching fixes from the DefectRepros batch:

  • Concurrent writes to different ImageCache limits could overwrite each other: each setter went through Cache.conf's separate get and set, so a countLimit write on one thread could put back the old costLimit written on another. The limits are now updated under the lock with updateConf; value(forKey:) is untouched.
  • Concurrent requests for the same URL with different imageIDs were coalesced into one TaskLoadImage, which stored the image only under the first request's keys, so the second ID missed the memory cache and downloaded again. The custom imageID is now part of TaskLoadImageKey (nil for default requests, so the common path hashes nothing extra); the data is still fetched once, by URL. This also fixes ImagePrefetcher deduplicating and stopping such requests under one key.
  • containsCachedImage(caches: .disk) and containsData(for:) returned true for a request with .disableDiskCacheReads (or .reloadIgnoringCachedData) while cachedData and cachedImage returned nil for it: they queried the data cache without the read guard the other methods have.
  • storeCachedImage encoded the image before checking whether there is a data cache or whether the request allows disk writes, so with the default configuration (no data cache) every call paid a synchronous encode and threw the result away. The data cache and the write option are now checked first.

@kean
kean force-pushed the fix/cache-limits-keys-contains branch from 1c54341 to bd01459 Compare September 26, 2026 20:40
@kean
kean force-pushed the fix/cache-limits-keys-contains branch 3 times, most recently from 66c00a2 to c1ce796 Compare November 1, 2026 15:14
kean added 5 commits November 2, 2026 19:19
Each setter went through Cache.conf's separate get and set, so two threads writing different limits could put back each other's old value.
Concurrent requests for one URL with different imageIDs shared a TaskLoadImage, which stored the image under the first request's keys only. The data is still fetched once, by URL.
Both queried the data cache directly, without the read guard that cachedData(for:) has, so they said yes for a request the pipeline would never read from disk for.
… disk

The image was encoded before the data cache and .disableDiskCacheWrites were checked, so with no data cache (the default) every call paid a synchronous encode and threw the result away.
@kean
kean force-pushed the fix/cache-limits-keys-contains branch from c1ce796 to d861edd Compare November 3, 2026 00:51

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant