-
Notifications
You must be signed in to change notification settings - Fork 521
Add --max-concurrent-downloads flag for parallel layer downloads #716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| @@ -0,0 +1,109 @@ | |||
| #!/usr/bin/env swift | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this and test_parameter_flow.swift in the top level directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should they belong in Tests/CLITests/Subcommands/Images/?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this might be a good place for the tests.
| guard err.isCode(.notFound) else { | ||
| throw err | ||
| } | ||
| return try await Self.pull(reference: reference, platform: platform, scheme: scheme, progressUpdate: progressUpdate) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm somewhat confused by the commit description however. I thought we had found we do pull layers in parallel, but that it's just a hardcoded 8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry I originally thought it wasn't pulling in parallel but I noticed it was hardcoded later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated original issue to more accurately reflect this: #715
c843892 to
cc15745
Compare
cc15745 to
26ebe63
Compare
Implements concurrent layer downloads to improve image pull performance by fetching multiple layers simultaneously instead of sequentially.
26ebe63 to
53e6c45
Compare
|
@dcantah anything else needed to merge this? |
|
@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 😄 |
jglogan
left a comment
There was a problem hiding this 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!
| .package(url: "https://github.com/orlandos-nl/DNSClient.git", from: "2.4.1"), | ||
| .package(url: "https://github.com/Bouke/DNS.git", from: "1.2.0"), | ||
| .package(url: "https://github.com/apple/containerization.git", exact: Version(stringLiteral: scVersion)), | ||
| .package(url: "https://github.com/apple/containerization.git", branch: "main"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sbhavani As Danny mentioned this needs to be reverted. If you rebase the PR, scVersion should be at the point where your ImageStore.pull() call will build without issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this has to be reverted, and scVersion should be updated to 0.11.0. Services/ContainerSandboxService/SandboxService.swift will need to be updated after that.
|
|
||
| public init(disableProgressUpdates: Bool, maxConcurrentDownloads: Int) { | ||
| self.disableProgressUpdates = disableProgressUpdates | ||
| self.maxConcurrentDownloads = maxConcurrentDownloads |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reason behind putting this in the progress group?
The problem I see here is that any command that wants to present the --progress flag (--disable-progress-updates is gone, apologies for letting this PR go so long so as to force a rebase here) will also see --max-concurrent-downloads whether downloads are relevant to the other command or not. Is there a better home for this? Or do we need to create another reusable group especially for download-related options?
I don't see any harm in copy/pasting this option into each command that needs it either, unless there's simply too many of them.
no problem! I'll take a look and make the changes |
There was a problem hiding this 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.
| @@ -0,0 +1,109 @@ | |||
| #!/usr/bin/env swift | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The project is currently using camelCase for filenames.
| .package(url: "https://github.com/orlandos-nl/DNSClient.git", from: "2.4.1"), | ||
| .package(url: "https://github.com/Bouke/DNS.git", from: "1.2.0"), | ||
| .package(url: "https://github.com/apple/containerization.git", exact: Version(stringLiteral: scVersion)), | ||
| .package(url: "https://github.com/apple/containerization.git", branch: "main"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this has to be reverted, and scVersion should be updated to 0.11.0. Services/ContainerSandboxService/SandboxService.swift will need to be updated after that.
| /// Starts multiple concurrent tasks and returns them. | ||
| /// - Parameter count: The number of concurrent tasks to start. | ||
| /// - Returns: An array of ProgressTask instances. | ||
| public func startConcurrentTasks(count: Int) -> [ProgressTask] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is unused and can be removed.
| /// - Parameters: | ||
| /// - task: The task whose progress is being updated. | ||
| /// - progressUpdate: The handler to invoke when progress updates are received. | ||
| public static func concurrentHandler(for task: ProgressTask, from progressUpdate: @escaping ProgressUpdateHandler) -> ProgressUpdateHandler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is unused and can be removed.
|
|
||
| let insecure = try scheme.schemeFor(host: host) == .http | ||
| request.set(key: .insecureFlag, value: insecure) | ||
| request.set(key: .maxConcurrentDownloads, value: Int64(maxConcurrentDownloads)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we check that maxConcurrentDownloads > 0?
| @@ -0,0 +1,109 @@ | |||
| #!/usr/bin/env swift | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this might be a good place for the tests.
| public struct ProgressTask: Sendable, Equatable, Hashable { | ||
| private var id = UUID() | ||
| private var coordinator: ProgressTaskCoordinator | ||
| internal var coordinator: ProgressTaskCoordinator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the unused methods are removed, coordinator can be kept private.
| /// A type that coordinates progress tasks to ignore updates from completed tasks. | ||
| public actor ProgressTaskCoordinator { | ||
| var currentTask: ProgressTask? | ||
| var activeTasks: Set<ProgressTask> = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems the concurrent download occurs inside a single task. Can we simplify the logic and remove activeTasks and hash()?
Adds
--max-concurrent-downloadsflag tocontainer image pullfor configurable concurrent layer downloads.Fixes #715
Depends on apple/containerization#311
Usage:
Changes:
Performance: ~1.2-1.3x faster pulls for multi-layer images with higher concurrency
Tests: Included standalone tests verify concurrency behavior and parameter flow