Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/Compiler/Facilities/DiagnosticsLogger.fs
Original file line number Diff line number Diff line change
Expand Up @@ -949,9 +949,19 @@ module MultipleDiagnosticsLoggers =
try
// We want to restore the current diagnostics context when finished.
use _ = new CompilationGlobalsScope()
return! Async.Parallel computationsWithLoggers
let! results = Async.Parallel computationsWithLoggers
do! replayDiagnostics |> Async.AwaitTask
return results
finally
replayDiagnostics.Wait()
// When any of the computation throws, Async.Parallel may not start some remaining computations at all.
// We set dummy results for them to allow the task to finish and to not lose any already emitted diagnostics.
if not replayDiagnostics.IsCompleted then
let emptyLogger = CapturingDiagnosticsLogger("empty")

for tcs in diagnosticsReady do
tcs.TrySetResult(emptyLogger) |> ignore

replayDiagnostics.Wait()
}

let Sequential computations =
Expand Down
25 changes: 25 additions & 0 deletions tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,32 @@ module BuildGraphTests =

errorCountShouldBe 600

[<Fact>]
let ``MultipleDiagnosticsLoggers.Parallel finishes when any computation throws`` () =

let mutable count = 0
use _ = UseDiagnosticsLogger (CapturingDiagnosticsLogger "test logger")

let tasks = [
async { failwith "computation failed" }

for i in 1 .. 300 do
async {
Interlocked.Increment(&count) |> ignore
errorR (ExampleException $"{i}")
}
]

let run =
tasks |> MultipleDiagnosticsLoggers.Parallel |> Async.Catch |> Async.StartAsTask

Assert.True(
run.Wait(1000),
"MultipleDiagnosticsLoggers.Parallel did not finish."
)

// Diagnostics from all started tasks should be collected despite the exception.
errorCountShouldBe count


[<Fact>]
Expand Down