Skip to content

ImageCache.imageCachedType performs synchronous stat calls on caller thread, causing main-thread hangs under disk pressure #2512

@aliakhtar-hu

Description

@aliakhtar-hu

We're seeing production hangs. Representative stack trace (all frames on main thread):

ImageCache.imageCachedType(forKey:processorIdentifier:) calls into DiskStorage.Backend.isCached, which in turn calls DiskStorage.Backend.value(forKey:...)

swift// DiskStorage.swift

guard fileManager.fileExists(atPath: filePath) else { return nil }           // stat #1
let meta = try FileMeta(fileURL: fileURL, resourceKeys: [...])               // stat #2 (resource values)

Because KingfisherManager.retrieveImage → retrieveImageFromCache → imageCachedType runs synchronously on whatever queue called KingfisherWrapper.setImage, these stat calls land on the main thread whenever setImage is called from cellForRowAtIndexPath, collectionView(_:cellForItemAt:), or any other UIKit layout callback

libsystem_kernel    stat
Foundation          _FileManagerImpl._fileExists
Foundation          _NSFileManagerBridge.fileExists
Kingfisher          DiskStorage.Backend.value (DiskStorage.swift:260)
Kingfisher          DiskStorage.Backend.isCached (DiskStorage.swift:318)
Kingfisher          DiskStorage.Backend.isCached (DiskStorage.swift:301)
Kingfisher          ImageCache.imageCachedType (ImageCache.swift:924)
Kingfisher          KingfisherManager.retrieveImageFromCache (KingfisherManager.swift:594)
Kingfisher          KingfisherManager.retrieveImage (KingfisherManager.swift:400)
Kingfisher          KingfisherManager.retrieveImage (KingfisherManager.swift:377)
Kingfisher          KingfisherWrapper<T>.setImage (ImageView+Kingfisher.swift:320)
Kingfisher          KingfisherWrapper<T>.setImage (ImageView+Kingfisher.swift:86)
Kingfisher          KingfisherWrapper<T>.setImage (ImageView+Kingfisher.swift:173)
<App>               UIImageView.setKFImage (wrapper)
<App>               TileContainer.set
<App>               TableViewCell.updateTiles (forEach over tiles)
<App>               TableViewCell.set
UIKitCore           -[__UIDiffableDataSource tableView:cellForRowAtIndexPath:]
UIKitCore           -[UITableView _createPreparedCellForGlobalRow:...]
UIKitCore           -[UITableView _heightForRowAtIndexPath:]
UIKitCore           -[_UITableViewUpdateSupport _faultInRealHeightsOfNeededElements]
UIKitCore           -[UITableView _endCellAnimationsWithContext:]

Kingfisher 8.5.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions