Skip to content

downloadPriority is ignored when a request joins an in-flight download #2567

Description

@mini-min

When multiple requests share one in-flight download, the download priority is not handled per consumer. This surfaces in two ways.

1. A request joining a shared task has its downloadPriority silently dropped

In ImageDownloader.addDownloadTask, downloadPriority is applied only when a fresh URLSessionDataTask is created:

let downloadTask: DownloadTask
if let existingTask = sessionDelegate.task(for: context.url),
let existingDownloadTask = sessionDelegate.append(existingTask, callback: callback)
{
downloadTask = existingDownloadTask
} else {
let sessionDataTask = session.dataTask(with: context.request)
sessionDataTask.priority = context.options.downloadPriority
downloadTask = sessionDelegate.add(sessionDataTask, url: context.url, callback: callback)
}

A request that coalesces onto an existing task via sessionDelegate.append (L421 above) never affects the task priority.

Typical impact: an ImagePrefetcher starts a download at low priority, the cell becomes visible and requests the same URL at high priority — but the download stays at low priority, and the visible image loads slowly.

2. reducePriorityOnDisappear can degrade other consumers of the shared task

The option added in #2211 is implemented as a raw write to the shared task:

func reducePriorityOnDisappear() {
guard let downloadTask = downloadTask, loading == true else { return }
downloadTask.sessionTask?.task.priority = URLSessionTask.lowPriority
}

Since the URLSessionDataTask may be shared (two KFImages with the same URL, or a view plus a prefetcher), one view scrolling off-screen lowers the priority for every consumer still waiting on that URL — including a fully visible one. restorePriorityOnAppear() (L191) has the mirrored last-write-wins behavior.

History

#73 (2015) reported the same "joining request never updates priority" scenario.
It was addressed in c85a3fc by exposing a settable priority on the download task, shipped in 2.0.0.

The API survived through 4.x and was lost in the 5.0 downloader rewrite (5e26180). I couldn't find the removal mentioned in the changelog or migration notes, so it looks like an unintended casualty of the rewrite.

I'd be happy to work on a fix and submit a PR for this, if that sounds good to you.

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