Harden legacy Downloader background behavior and progress reporting#325
Harden legacy Downloader background behavior and progress reporting#325
Downloader background behavior and progress reporting#325Conversation
…collision Co-authored-by: Musa Deniev <45773032+musamuss@users.noreply.github.com>
Co-authored-by: Musa Deniev <45773032+musamuss@users.noreply.github.com>
…ngTo Co-authored-by: Musa Deniev <45773032+musamuss@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Hardens the legacy Downloader (kept for backward compatibility post swift-huggingface migration) by improving background-session behavior, progress reporting, and download file finalization safety.
Changes:
- Makes the background
URLSessionidentifier vary per destination to reduce collisions. - Guards progress calculation when
totalBytesExpectedToWriteis unknown/non-positive. - Copies the downloaded file to a “safe” temporary location before moving it to the final destination.
Comments suppressed due to low confidence (1)
Sources/Hub/Downloader.swift:420
- Copying the downloaded file (
copyItem) intosafeTempURLcan double disk usage and add significant I/O for large downloads. Since the file atlocationis only ephemeral after this callback returns, you canmoveItemtosafeTempURL(or directly todestination) inside the callback to persist it without an extra copy; also consider cleaning upsafeTempURLon failure (e.g.,defer+ conditional remove) to avoid leaving orphaned temp files whenmoveDownloadedFilethrows.
// Persist to a safe temporary path before leaving this delegate callback
let tempDir = fileManager.temporaryDirectory
let safeTempURL = tempDir.appendingPathComponent(UUID().uuidString + "_" + location.lastPathComponent)
do {
try fileManager.copyItem(at: location, to: safeTempURL)
// If the downloaded file already exists on the filesystem, overwrite it
try fileManager.moveDownloadedFile(from: safeTempURL, to: destination)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| self.chunkSize = chunkSize | ||
|
|
||
| let sessionIdentifier = "swift-transformers.hub.downloader" | ||
| let sessionIdentifier = "swift-transformers.hub.downloader.\(destination.lastPathComponent.hashValue)" |
There was a problem hiding this comment.
destination.lastPathComponent.hashValue is not stable across process launches (Swift hashes are intentionally randomized) and can collide. For background URLSessionConfiguration.background(withIdentifier:), the identifier must be deterministic to allow reconnecting to existing tasks after relaunch. Consider using a stable identifier derived from the full destination URL/path (e.g., a deterministic cryptographic hash or a sanitized/truncated absoluteString) instead of hashValue.
| let sessionIdentifier = "swift-transformers.hub.downloader.\(destination.lastPathComponent.hashValue)" | |
| let sessionIdentifier = "swift-transformers.hub.downloader.\(destination.absoluteString)" |
|
On second thought, Closing this. |
Most of the changes in #305 were superseded by our migration to swift-huggingface in #315. However, there were some useful changes there that are worth pulling in, even if
Downloaderis only kept around for backward compatibility — specifically: