-
Notifications
You must be signed in to change notification settings - Fork 830
Closed
Labels
Area-LibraryIssues for FSharp.Core not covered elsewhereIssues for FSharp.Core not covered elsewhereBugImpact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.(Internal MS Team use only) Describes an issue with moderate impact on existing code.
Description
When Async.Parallel is handling cancellation (via the token or a computation throwing) with e.g. 2000 items outstanding, the current implementation as of FSharp.Core 6.0.4 is such that the non-tail-recursive impl can blow the stack.
Repro steps
let [<Fact>] ``Async.Parallel blows stack when cancelling many`` () =
let gen (i : int) = async {
if i <> 0 then do! Async.Sleep i
else return failwith (string i) }
let count = 1800
let comps = Seq.init count gen
let result = Async.Parallel(comps, 16) |> Async.Catch |> Async.RunSynchronously
test <@ match result with
| Choice2Of2 e -> int e.Message < count
| x -> failwithf "unexpected %A" x @>Known workarounds
batch the work with Seq.ChunkBySize 1500, add an outer Async.Parallel call (distributing the degreeOfParallelism over the constituent calls, or using the same value but internally constraining it with Async.Throttle), Array.concat the results.
Related information
(1800 is the approx threshold with SDK 6.0.202 on MacOS x86 with Rider test runner)
Problem appears to be at
fsharp/src/FSharp.Core/async.fs
Line 1473 in 0006b73
| worker trampolineHolder |> unfake |
Metadata
Metadata
Assignees
Labels
Area-LibraryIssues for FSharp.Core not covered elsewhereIssues for FSharp.Core not covered elsewhereBugImpact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.(Internal MS Team use only) Describes an issue with moderate impact on existing code.