Add --max-concurrent-downloads flag for parallel layer downloads (#716)

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

Fixes #715
Depends on apple/containerization#311

**Usage**:
```bash
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

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Santosh Bhavani
2025-12-07 15:56:50 -03:00
committed by GitHub
co-authored by Claude
parent 1e19a4d6e3
commit f7bcb687fd
11 changed files with 84 additions and 11 deletions
@@ -59,11 +59,15 @@ public actor ImagesService {
return try await imageStore.list().map { $0.description.fromCZ }
}
public func pull(reference: String, platform: Platform?, insecure: Bool, progressUpdate: ProgressUpdateHandler?) async throws -> ImageDescription {
self.log.info("ImagesService: \(#function) - ref: \(reference), platform: \(String(describing: platform)), insecure: \(insecure)")
public func pull(reference: String, platform: Platform?, insecure: Bool, progressUpdate: ProgressUpdateHandler?, maxConcurrentDownloads: Int = 3) async throws
-> ImageDescription
{
self.log.info(
"ImagesService: \(#function) - ref: \(reference), platform: \(String(describing: platform)), insecure: \(insecure), maxConcurrentDownloads: \(maxConcurrentDownloads)")
let img = try await Self.withAuthentication(ref: reference) { auth in
try await self.imageStore.pull(
reference: reference, platform: platform, insecure: insecure, auth: auth, progress: ContainerizationProgressAdapter.handler(from: progressUpdate))
reference: reference, platform: platform, insecure: insecure, auth: auth, progress: ContainerizationProgressAdapter.handler(from: progressUpdate),
maxConcurrentDownloads: maxConcurrentDownloads)
}
guard let img else {
throw ContainerizationError(.internalError, message: "failed to pull image \(reference)")