-
Notifications
You must be signed in to change notification settings - Fork 201
[Proposal] Update ProgressManager Proposal #1335
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
Merged
chloe-yeo
merged 35 commits into
swiftlang:main
from
chloe-yeo:proposal/progress-reporter
Jun 30, 2025
Merged
Changes from 26 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
82c0eba
ProgressReporter proposal
chloe-yeo f3e5fde
reword future directions section + fix typo
chloe-yeo 6c98f1d
fix spacing
chloe-yeo 4b15850
refactor LocalizedDescriptionOptions
chloe-yeo 3e59ff1
edit future directions
chloe-yeo 5ed834e
update ProgressReporter Pitch to V2
chloe-yeo 21dffe9
update proposal to latest version
chloe-yeo 93b855d
fix spacing
chloe-yeo 720cf0c
v3 updates
chloe-yeo 6384a3a
Merge branch 'swiftlang:main' into proposal/progress-reporter
chloe-yeo 8d6c552
Update review status for SF-0023 to active review
b7b9c64
Merge branch 'swiftlang:main' into proposal/progress-reporter
chloe-yeo 90e4d54
Merge branch 'swiftlang:main' into proposal/progress-reporter
chloe-yeo 7d92d2d
Round 2 Pitch
chloe-yeo 8aa6815
Merge branch 'swiftlang:main' into proposal/progress-reporter
chloe-yeo db9c100
fix typo
chloe-yeo 44de6ee
update proposal to v5
chloe-yeo 8293405
add code documentation
chloe-yeo 4fab79b
Update status for SF-0023 to 2nd Review
iCharlesHu 082a48d
Update 0023-progress-reporter.md
chloe-yeo b489c17
Merge branch 'main' into proposal/progress-reporter
chloe-yeo b454399
update name + add total and values to ProgressReporter
chloe-yeo 729918f
Merge branch 'swiftlang:main' into proposal/progress-reporter
chloe-yeo 122dd93
update proposal with minor updates
chloe-yeo 2275867
expand future directions
chloe-yeo 0f1c9fd
fix typo
chloe-yeo ac33af6
update proposal
chloe-yeo 10dae78
reformatting
chloe-yeo 3d88bb1
expand alternatives considered + mark accepted
chloe-yeo 397b9d5
fix formatting
chloe-yeo 1463145
fix typos
chloe-yeo d6cb84c
fix formatting
chloe-yeo dbf6eb2
fix method description
chloe-yeo 3e4657e
remove implementation detail
chloe-yeo 611c4b2
add more discussions about additional properties
chloe-yeo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# `ProgressReporter`: Progress Reporting in Swift Concurrency | ||
# `ProgressManager`: Progress Reporting in Swift Concurrency | ||
|
||
* Proposal: SF-0023 | ||
* Author(s): [Chloe Yeo](https://github.com/chloe-yeo) | ||
|
@@ -33,6 +33,9 @@ | |
- Moving `FormatStyle` to separate future proposal | ||
* **v5** Minor Updates: | ||
- Renamed `manager(totalCount:)` to `start(totalCount)` | ||
- Changed the return type of `values(of:)` to be an array of non-optional values | ||
- Clarify cycle-detection behavior in `assign(count:to:)` at runtime | ||
- Expanded Future Directions | ||
- Expanded Alternatives Considered | ||
|
||
## Table of Contents | ||
|
@@ -153,12 +156,12 @@ Another recommended usage pattern of `Progress`, which involves the `ProgressRep | |
|
||
### `ProgressManager` API | ||
|
||
We propose introducing a new progress reporting type called `ProgressManager`. `ProgressManager` is used to report progress. | ||
We propose introducing a new progress reporting type called `ProgressManager`. `ProgressManager` is used to manage the composition of progress by either assigning it, or completing it. | ||
|
||
In order to compose progress into trees, we also introduce two more types: | ||
|
||
1. `Subprogress`: A `~Copyable` type, used when a `ProgressManager` wishes to assign a portion of its total progress to an `async` function. | ||
2. `ProgressReporter`: A class used to report progress to interested observers. This includes one or more other `ProgressManager`s, which may incorporate those updates into their own progress. | ||
2. `ProgressReporter`: A class used to report progress of `ProgressManager` to interested observers. This includes one or more other `ProgressManager`s, which may incorporate those updates into their own progress. | ||
|
||
```mermaid | ||
block-beta | ||
|
@@ -516,6 +519,8 @@ overall.addChild(subprogressThree, withPendingUnitCount: 1) | |
|
||
/// Adds a `ProgressReporter` as a child, with its progress representing a portion of `self`'s progress. | ||
/// | ||
/// If a cycle is detected, this will cause a crash at runtime. | ||
/// | ||
/// - Parameters: | ||
/// - output: A `ProgressReporter` instance. | ||
/// - count: The portion of `totalCount` to be delegated to the `ProgressReporter`. | ||
|
@@ -534,7 +539,7 @@ overall.addChild(subprogressThree, withPendingUnitCount: 1) | |
/// | ||
/// - Parameter property: Type of property. | ||
/// - Returns: Array of values for property. | ||
public func values<P: ProgressManager.Property>(of property: P.Type) -> [P.Value?] | ||
public func values<P: ProgressManager.Property>(of property: P.Type) -> [P.Value] | ||
|
||
/// Returns the aggregated result of values where type of property is `AdditiveArithmetic`. | ||
/// All values are added together. | ||
|
@@ -601,6 +606,20 @@ public struct Subprogress: ~Copyable, Sendable { | |
public func withProperties<T, E: Error>( | ||
_ closure: (sending ProgressManager.Values) throws(E) -> sending T | ||
) throws(E) -> T | ||
|
||
/// Returns an array of values for specified property in subtree. | ||
/// | ||
/// - Parameter property: Type of property. | ||
/// - Returns: Array of values for property. | ||
public func values<P: ProgressManager.Property>(of property: P.Type) -> [P.Value] | ||
|
||
/// Returns the aggregated result of values where type of property is `AdditiveArithmetic`. | ||
/// All values are added together. | ||
/// | ||
/// - Parameters: | ||
/// - property: Type of property. | ||
/// - values: Sum of values. | ||
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. Is this a copy-pasta leftover? 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. Yep, thanks for catching this, will fix this! |
||
public func total<P: ProgressManager.Property>(of property: P.Type) -> P.Value where P.Value : AdditiveArithmetic | ||
} | ||
``` | ||
|
||
|
@@ -780,6 +799,9 @@ To further safeguard developers from making mistakes of over-assigning or under- | |
### Support for Non-Integer Formats of Progress Updates | ||
To handle progress values from other sources that provide progress updates as non-integer formats such as `Double`, we can introduce a way for `ProgressManager` to either be instantiated with non-integer formats, or a peer instance of `ProgressManager` that works with `ProgressManager` to compose a progress graph. | ||
|
||
### Support for Decomposition of Progress / Display of Hierarchy of Progress Subtree | ||
If there happens to be greater demand of a functionality to either decompose a `ProgressManager` or `ProgressReporter` into its constituents, or to display the hierarchy of the subtree with a `ProgressManager` or `ProgressReporter` at its root, we can introduce additive changes to this API. | ||
|
||
## Alternatives considered | ||
|
||
### Alternative Names | ||
|
@@ -899,7 +921,7 @@ We considered introducing a `localizedDescription(including:)` method, which ret | |
The existing `Progress` provides support for cancelling, pausing and resuming an ongoing operation tracked by an instance of `Progress`, and propagates these actions down to all of its children. We decided to not introduce support for this behavior as there is support in cancelling a `Task` via `Task.cancel()` in Swift structured concurrency. The absence of support for cancellation, pausing and resuming in `ProgressManager` helps to clarify the scope of responsibility of this API, which is to report progress, instead of owning a task and performing actions on it. | ||
|
||
### Handling Cancellation by Checking Task Cancellation or Allowing Incomplete Progress after Task Cancellation | ||
We considered adding a `Task.isCancelled` check in the `complete(count:)` method so that calls to `complete(count:)` from a `Task` that is cancelled becomes a no-op. We have also considered not completing the progress to reflect the fact that no futher calls to `complete(count:)` are made after a `Task` is cancelled. However, in order to make sure that there is always a consistent state for progress independent of state of task, the `ProgressManager` will always finish before being deinitialized. THROW ERROR INSTEAD; catch error use error handling, if want to provide metadata for the cancellation - use custom property | ||
We considered adding a `Task.isCancelled` check in the `complete(count:)` method so that calls to `complete(count:)` from a `Task` that is cancelled becomes a no-op. We have also considered not completing the progress to reflect the fact that no futher calls to `complete(count:)` are made after a `Task` is cancelled. However, in order to make sure that there is always a consistent state for progress independent of state of task, the `ProgressManager` will always finish before being deinitialized. | ||
|
||
### Introduce `totalCount` and `completedCount` properties as `UInt64` | ||
We considered using `UInt64` as the type for `totalCount` and `completedCount` to support the case where developers use `totalCount` and `completedCount` to track downloads of larger files on 32-bit platforms byte-by-byte. However, developers are not encouraged to update progress byte-by-byte, and should instead set the counts to the granularity at which they want progress to be visibly updated. For instance, instead of updating the download progress of a 10,000 bytes file in a byte-by-byte fashion, developers can instead update the count by 1 for every 1,000 bytes that has been downloaded. In this case, developers set the `totalCount` to 10 instead of 10,000. To account for cases in which developers may want to report the current number of bytes downloaded, we added `totalByteCount` and `completedByteCount` to `ProgressManager.Properties`, which developers can set and display using format style. | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back 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.
Can we have a sentence or two for this and the below API in the section about properties? I don't think I see the discussion in this proposal
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.
Yep, I can add this!
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.
Added :)