Skip to content

Conversation

@sbhavani
Copy link
Contributor

@sbhavani sbhavani commented Oct 4, 2025

Adds --max-concurrent-downloads flag to container image pull for configurable concurrent layer downloads.

Fixes #715
Depends on apple/containerization#311

Usage:

container image pull nginx:latest --max-concurrent-downloads 6

Changes:

  • Add CLI flag (default: 3)
  • Thread parameter through XPC stack
  • Update to use forked containerization with configurable concurrency

Performance: ~1.2-1.3x faster pulls for multi-layer images with higher concurrency

Tests: Included standalone tests verify concurrency behavior and parameter flow

@dcantah dcantah marked this pull request as draft October 10, 2025 00:54
@sbhavani sbhavani force-pushed the feature/parallel-layer-downloads branch from c843892 to cc15745 Compare October 14, 2025 06:21
@sbhavani sbhavani marked this pull request as ready for review October 14, 2025 06:23
@sbhavani sbhavani force-pushed the feature/parallel-layer-downloads branch from cc15745 to 26ebe63 Compare October 14, 2025 06:25
Implements concurrent layer downloads to improve image pull performance by fetching multiple layers simultaneously instead of sequentially.
@sbhavani sbhavani force-pushed the feature/parallel-layer-downloads branch from 26ebe63 to 53e6c45 Compare October 14, 2025 06:27
@sbhavani
Copy link
Contributor Author

@dcantah anything else needed to merge this?

@dcantah
Copy link
Member

dcantah commented Oct 21, 2025

@sbhavani Yes. We need a tag of Containerization that has the changes. I'm making some changes over there but should have a tag out within the next day or so and then we can bump to this. We should not have our dependency on Containerization be to a branch, and especially not main 😄

Copy link
Contributor

@jglogan jglogan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbhavani Just a couple of nits if you still have time to move this forward. Thank you for contributing!

@sbhavani
Copy link
Contributor Author

@sbhavani Just a couple of nits if you still have time to move this forward. Thank you for contributing!

no problem! I'll take a look and make the changes

Copy link
Contributor

@dkovba dkovba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution 👍
The default value 3 seems reasonable.

@sbhavani sbhavani force-pushed the feature/parallel-layer-downloads branch from e02e2ff to 21ac59f Compare November 15, 2025 03:50
@sbhavani sbhavani requested a review from dkovba November 15, 2025 04:06
Copy link
Contributor

@dkovba dkovba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please run make fmt to pass the PR checks.

@Option(name: .long, help: ArgumentHelp("Progress type (format: none|ansi)", valueName: "type"))
public var progress: ProgressType = .ansi

@Option(name: .long, help: "Maximum number of concurrent layer downloads (default: 3)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adityaramani Should we use the word "layer" or "blob" here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use just "concurrent downloads"

@apple apple deleted a comment from 0777888212 Nov 19, 2025
@sbhavani sbhavani requested a review from dkovba November 23, 2025 05:47
Copy link
Contributor

@dkovba dkovba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix merge conflicts.

Resolved conflicts in:
- Package.resolved: Updated to containerization 0.16.0 and new dependency hashes
- ClientImage.swift: Preserved maxConcurrentDownloads parameter in fetch() method
  while adding new calculateDiskUsage() method from upstream
- TestCLIImages.swift: Kept both maxConcurrentDownloads tests and new
  testImageSaveAndLoadStdinStdout test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@sbhavani sbhavani requested a review from dkovba December 4, 2025 16:41
Copy link
Contributor

@dkovba dkovba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@dkovba dkovba requested a review from jglogan December 4, 2025 19:28
Removed duplicate declaration of set(key:value:) with Int64 parameter that was causing build failure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

@jglogan jglogan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbhavani looks good, just a couple final nits related to messages...

reference: String, platform: Platform? = nil, scheme: RequestScheme = .auto, progressUpdate: ProgressUpdateHandler? = nil, maxConcurrentDownloads: Int = 3
) async throws -> ClientImage {
guard maxConcurrentDownloads > 0 else {
throw ContainerizationError(.invalidArgument, message: "--max-concurrent-downloads must be greater than 0, got \(maxConcurrentDownloads)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't refer to command line arguments inside the client.

Should read "maximum number of concurrent downloads must be..."

@Option(name: .long, help: ArgumentHelp("Progress type (format: none|ansi)", valueName: "type"))
public var progress: ProgressType = .ansi

@Option(name: .long, help: "Maximum number of concurrent layer downloads (default: 3)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use just "concurrent downloads"


#expect(status != 0, "Expected command to fail with maxConcurrentDownloads=0")
#expect(
error.contains("--max-concurrent-downloads must be greater than 0"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix to match the change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made the update

@jglogan jglogan merged commit f7bcb68 into apple:main Dec 7, 2025
3 of 4 checks passed
@sbhavani sbhavani deleted the feature/parallel-layer-downloads branch December 7, 2025 20:26
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.

[Request]: Support configurable parallel layer downloads during image pull

5 participants