-
Couldn't load subscription status.
- Fork 499
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| #!/usr/bin/env swift | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. should they belong in Tests/CLITests/Subcommands/Images/? |
||
|
|
||
| import Foundation | ||
|
|
||
| func testConcurrentDownloads() async throws { | ||
| print("Testing concurrent download behavior...\n") | ||
|
|
||
| // Track concurrent task count | ||
| actor ConcurrencyTracker { | ||
| var currentCount = 0 | ||
| var maxObservedCount = 0 | ||
| var completedTasks = 0 | ||
|
|
||
| func taskStarted() { | ||
| currentCount += 1 | ||
| maxObservedCount = max(maxObservedCount, currentCount) | ||
| } | ||
|
|
||
| func taskCompleted() { | ||
| currentCount -= 1 | ||
| completedTasks += 1 | ||
| } | ||
|
|
||
| func getStats() -> (max: Int, completed: Int) { | ||
| return (maxObservedCount, completedTasks) | ||
| } | ||
|
|
||
| func reset() { | ||
| currentCount = 0 | ||
| maxObservedCount = 0 | ||
| completedTasks = 0 | ||
| } | ||
| } | ||
|
|
||
| let tracker = ConcurrencyTracker() | ||
|
|
||
| // Test with different concurrency limits | ||
| for maxConcurrent in [1, 3, 6] { | ||
| await tracker.reset() | ||
|
|
||
| // Simulate downloading 20 layers | ||
| let layerCount = 20 | ||
| let layers = Array(0..<layerCount) | ||
|
|
||
| print("Testing maxConcurrent=\(maxConcurrent) with \(layerCount) layers...") | ||
|
|
||
| let startTime = Date() | ||
|
|
||
| try await withThrowingTaskGroup(of: Void.self) { group in | ||
| var iterator = layers.makeIterator() | ||
|
|
||
| // Start initial batch based on maxConcurrent | ||
| for _ in 0..<maxConcurrent { | ||
| if iterator.next() != nil { | ||
| group.addTask { | ||
| await tracker.taskStarted() | ||
| try await Task.sleep(nanoseconds: 10_000_000) | ||
| await tracker.taskCompleted() | ||
| } | ||
| } | ||
| } | ||
| for try await _ in group { | ||
| if iterator.next() != nil { | ||
| group.addTask { | ||
| await tracker.taskStarted() | ||
| try await Task.sleep(nanoseconds: 10_000_000) | ||
| await tracker.taskCompleted() | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| let duration = Date().timeIntervalSince(startTime) | ||
| let stats = await tracker.getStats() | ||
|
|
||
| print(" ✓ Completed: \(stats.completed)/\(layerCount)") | ||
| print(" ✓ Max concurrent: \(stats.max)") | ||
| print(" ✓ Duration: \(String(format: "%.3f", duration))s") | ||
|
|
||
| guard stats.max <= maxConcurrent + 1 else { | ||
| throw TestError.concurrencyLimitExceeded | ||
| } | ||
|
|
||
| guard stats.completed == layerCount else { | ||
| throw TestError.incompleteTasks | ||
| } | ||
|
|
||
| print(" ✅ PASSED\n") | ||
| } | ||
|
|
||
| print("All tests passed!") | ||
| } | ||
|
|
||
| enum TestError: Error { | ||
| case concurrencyLimitExceeded | ||
| case incompleteTasks | ||
| } | ||
|
|
||
| Task { | ||
| do { | ||
| try await testConcurrentDownloads() | ||
| exit(0) | ||
| } catch { | ||
| print("Test failed: \(error)") | ||
| exit(1) | ||
| } | ||
| } | ||
|
|
||
| RunLoop.main.run() | ||
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.
Uh oh!
There was an error while loading. Please reload this page.
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