feat(Task, Async): parallelLimit, sequential, startAsyncImmediate - #20294
Conversation
✅ No release notes required |
2868b43 to
8d995fa
Compare
c7f4834 to
0279f13
Compare
There was a problem hiding this comment.
Pull request overview
Adds bounded-parallelism helpers to FSharp.Core’s Async and Task modules (parallelLimit / parallelDoLimit), along with unit tests, surface-area baselines, and release notes, to support controlled concurrency for async/task workflows.
Changes:
- Add
Async.parallelLimit/Async.parallelDoLimitwrappers overAsync.ParallelwithmaxDegreeOfParallelism. - Add
Task.parallelLimit/Task.parallelDoLimitimplemented viaSemaphoreSlim+Task.WhenAll, flowing a providedCancellationTokento task factories. - Add unit tests + surface area baseline updates + release note entry for the new APIs.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/TaskModuleFunctions.fs | Adds unit tests for Task.parallelLimit / Task.parallelDoLimit (results + concurrency cap). |
| tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModuleFunctions.fs | Adds unit tests for Async.parallelLimit / Async.parallelDoLimit. |
| tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl | Surface-area baseline update for new AsyncModule/TaskModule members (netstandard2.1, release). |
| tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl | Surface-area baseline update (netstandard2.1, debug). |
| tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl | Surface-area baseline update (netstandard2.0, release). |
| tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl | Surface-area baseline update (netstandard2.0, debug). |
| src/FSharp.Core/tasks.fsi | Public API + docs for Task.parallelLimit / Task.parallelDoLimit. |
| src/FSharp.Core/tasks.fs | Implementation of Task.parallelLimit / Task.parallelDoLimit. |
| src/FSharp.Core/async.fsi | Public API + docs for Async.parallelLimit / Async.parallelDoLimit. |
| src/FSharp.Core/async.fs | Implementation of Async.parallelLimit / Async.parallelDoLimit. |
| docs/release-notes/.FSharp.Core/11.0.100.md | Release note entry for the new bounded-parallelism helpers. |
Suppressed comments (1)
src/FSharp.Core/tasks.fs:820
SemaphoreSlimdisposal is wired up via aContinueWith, but if enumeratingcomputationsthrows while building theTask.WhenAllinput array, the semaphore is leaked (the continuation is never attached). Usinguse sem = ...and dropping the continuation avoids the leak and simplifies the implementation.
allTask.ContinueWith(
(fun (_: Task<'T[]>) -> sem.Dispose()),
CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
7c29f61 to
5610b5c
Compare
dc664b9 to
aa67147
Compare
b39e065 to
6d75944
Compare
|
🔍 Tooling Safety Check — Affects-Test-Tooling
|
|
@T-Gro if you can chuck an AI or human review on this I'll attend to it @T-Gro @TheAngryByrd In my musings in fsharp/fslang-suggestions#685 (comment) I noted that parallelLimit and friends should probably make an internal linked CT and cancel siblings where one of the computations faults in order to match the @TheAngryByrd @T-Gro Any thoughts on whether we should add Async.StartChild(computation, externalCt) per fsharp/fslang-suggestions#685 into the mix? @TheAngryByrd Are there any other common things that might belong in the modules that get heavy usage, e.g.
|
66b3900 to
95690f9
Compare
# This is the 1st commit message: review: correct handling under exception in enumeration # The commit message #2 will be skipped: # f
beea0fa to
22971e5
Compare
1a08a72 to
2108037
Compare
|
@T-Gro bumping #20294 (comment) The devil makes work for idle hands, so I added Let me know if either is a step too far - IME this is common, and the |
14cdc4f to
6281118
Compare
Part of the helpers/signatures proposed in fsharp/fslang-suggestions#1467
Resolves fsprojects/FSharp.Control.TaskSeq#143
Resolves fsharp/fslang-suggestions#1467
Adds
parallelLimit,parallelDoLimit,sequentialandsequentialDofunctions formodule Asyncandmodule Task(excludingAsync.sequentialasAsync.Sequentialalready has same signature ontype Async).Adds
Task.startAsyncImmediate(pipeline-friendly/pit-of-success alias forAsync.StartImmediateAsTaskthat forces passing of aCancellationToken)LimitvsThrottlednaming is/was discussed in the linked issues; any discussion on naming should happen therecc @TheAngryByrd This replicates functionality in FsToolkit.ErrorHandling so reviews would be much appreciated (and/or feel free to @ in anyone relevant)
cc @xperiandri
Task.parallelLimithas same sig asCancelableTask.whenAllThrottledin #20128 (I intend to take the enhancement and review comments from there into account too)Checklist:
Task.sequentialDo: CT -> seq<CT->Task<unit>>(same logic without result collector in mix)Task.startAsyncImmediate: CT -> Async'T> ->Task<'T>feat(Task, Async): parallelLimit, parallelDoLimit bartelink/fsharp#2 (comment) TaskEx: Async.startImmediateAsTask fsprojects/FSharp.Control.TaskSeq#142 Async/Task interop/cancellation/limits fsharp/fslang-suggestions#1467