From 3f2359fadcbca0fbfdd2ea907a12ddbf8fe2cb3f Mon Sep 17 00:00:00 2001 From: Jakub Majocha Date: Tue, 23 Jan 2024 20:52:13 +0100 Subject: [PATCH 1/6] add test --- .../CompilerService/AsyncMemoize.fs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs index 71dbb5c957f..c9cab9688b7 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs @@ -211,6 +211,39 @@ let ``Job is restarted if first requestor cancels but keeps running if second re type ExpectedException() = inherit Exception() +[] +let internal ``NodeCode preserves DiagnosticsThreadStatics`` () = + let job _ = node { + do! Random.Shared.Next 10 |> Async.Sleep |> NodeCode.AwaitAsync + } + + let work (phase: BuildPhase) = + node { + use _ = new CompilationGlobalsScope(DiscardErrorsLogger, phase) + let! _ = Seq.init 8 job |> NodeCode.Parallel + Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase) + } + + let phases = [| + BuildPhase.DefaultPhase + BuildPhase.Compile + BuildPhase.Parameter + BuildPhase.Parse + BuildPhase.TypeCheck + BuildPhase.CodeGen + BuildPhase.Optimize + BuildPhase.IlxGen + BuildPhase.IlGen + BuildPhase.Output + BuildPhase.Interactive + |] + + let pickRandomPhase _ = phases[Random.Shared.Next phases.Length] + Seq.init 100 pickRandomPhase + |> Seq.map (work >> Async.AwaitNodeCode) + |> Async.Parallel + |> Async.RunSynchronously + [] let ``Stress test`` () = From 5f8250e8ad047767b6f69430267ba5869a97751d Mon Sep 17 00:00:00 2001 From: Jakub Majocha Date: Tue, 23 Jan 2024 22:12:55 +0100 Subject: [PATCH 2/6] rand --- .../CompilerService/AsyncMemoize.fs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs index c9cab9688b7..e1925ca4d49 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs @@ -213,8 +213,12 @@ type ExpectedException() = [] let internal ``NodeCode preserves DiagnosticsThreadStatics`` () = + let random = + let rng = Random() + fun n -> rng.Next n + let job _ = node { - do! Random.Shared.Next 10 |> Async.Sleep |> NodeCode.AwaitAsync + do! random 10 |> Async.Sleep |> NodeCode.AwaitAsync } let work (phase: BuildPhase) = @@ -238,7 +242,7 @@ let internal ``NodeCode preserves DiagnosticsThreadStatics`` () = BuildPhase.Interactive |] - let pickRandomPhase _ = phases[Random.Shared.Next phases.Length] + let pickRandomPhase _ = phases[random phases.Length] Seq.init 100 pickRandomPhase |> Seq.map (work >> Async.AwaitNodeCode) |> Async.Parallel From 6b1048a88848f06ebbc9c2f8c9154ef5ba93da12 Mon Sep 17 00:00:00 2001 From: Petr Pokorny Date: Wed, 24 Jan 2024 15:30:17 +0100 Subject: [PATCH 3/6] This should fix it --- src/Compiler/Facilities/BuildGraph.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Facilities/BuildGraph.fs b/src/Compiler/Facilities/BuildGraph.fs index 1df58c1024b..780f54178f7 100644 --- a/src/Compiler/Facilities/BuildGraph.fs +++ b/src/Compiler/Facilities/BuildGraph.fs @@ -193,7 +193,7 @@ type NodeCode private () = } static member Parallel(computations: NodeCode<'T> seq) = - computations |> Seq.map (fun (Node x) -> x) |> Async.Parallel |> Node + computations |> Seq.map (fun (Node x) -> x) |> Async.Parallel |> wrapThreadStaticInfo |> Node [] module GraphNode = From a05db3b32ccd528c5414af09922d9e6618c18439 Mon Sep 17 00:00:00 2001 From: Jakub Majocha Date: Wed, 24 Jan 2024 15:40:47 +0100 Subject: [PATCH 4/6] check inner computation --- .../CompilerService/AsyncMemoize.fs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs index e1925ca4d49..d926ddbc98d 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs @@ -217,14 +217,15 @@ let internal ``NodeCode preserves DiagnosticsThreadStatics`` () = let rng = Random() fun n -> rng.Next n - let job _ = node { + let job phase _ = node { do! random 10 |> Async.Sleep |> NodeCode.AwaitAsync + Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase) } let work (phase: BuildPhase) = node { use _ = new CompilationGlobalsScope(DiscardErrorsLogger, phase) - let! _ = Seq.init 8 job |> NodeCode.Parallel + let! _ = Seq.init 8 (job phase) |> NodeCode.Parallel Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase) } From 9a3e774f3c317c5bb0a1ead07a8fd8fd44a90147 Mon Sep 17 00:00:00 2001 From: Jakub Majocha <1760221+majocha@users.noreply.github.com> Date: Wed, 24 Jan 2024 17:03:50 +0100 Subject: [PATCH 5/6] Update src/Compiler/Facilities/BuildGraph.fs Co-authored-by: Petr Pokorny --- src/Compiler/Facilities/BuildGraph.fs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Facilities/BuildGraph.fs b/src/Compiler/Facilities/BuildGraph.fs index 780f54178f7..71f4d3da991 100644 --- a/src/Compiler/Facilities/BuildGraph.fs +++ b/src/Compiler/Facilities/BuildGraph.fs @@ -193,7 +193,19 @@ type NodeCode private () = } static member Parallel(computations: NodeCode<'T> seq) = - computations |> Seq.map (fun (Node x) -> x) |> Async.Parallel |> wrapThreadStaticInfo |> Node + let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger + let phase = DiagnosticsThreadStatics.BuildPhase + + computations + |> Seq.map (fun (Node x) -> + async { + DiagnosticsThreadStatics.DiagnosticsLogger <- diagnosticsLogger + DiagnosticsThreadStatics.BuildPhase <- phase + return! x + }) + |> Async.Parallel + |> wrapThreadStaticInfo + |> Node [] module GraphNode = From 1e0c398b1e2a1d7dc555ed55fae4761ccc23884a Mon Sep 17 00:00:00 2001 From: Jakub Majocha Date: Wed, 24 Jan 2024 18:42:27 +0100 Subject: [PATCH 6/6] move test --- .../CompilerService/AsyncMemoize.fs | 38 ------------------ .../BuildGraphTests.fs | 40 +++++++++++++++++++ 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs index d926ddbc98d..71dbb5c957f 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs @@ -211,44 +211,6 @@ let ``Job is restarted if first requestor cancels but keeps running if second re type ExpectedException() = inherit Exception() -[] -let internal ``NodeCode preserves DiagnosticsThreadStatics`` () = - let random = - let rng = Random() - fun n -> rng.Next n - - let job phase _ = node { - do! random 10 |> Async.Sleep |> NodeCode.AwaitAsync - Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase) - } - - let work (phase: BuildPhase) = - node { - use _ = new CompilationGlobalsScope(DiscardErrorsLogger, phase) - let! _ = Seq.init 8 (job phase) |> NodeCode.Parallel - Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase) - } - - let phases = [| - BuildPhase.DefaultPhase - BuildPhase.Compile - BuildPhase.Parameter - BuildPhase.Parse - BuildPhase.TypeCheck - BuildPhase.CodeGen - BuildPhase.Optimize - BuildPhase.IlxGen - BuildPhase.IlGen - BuildPhase.Output - BuildPhase.Interactive - |] - - let pickRandomPhase _ = phases[random phases.Length] - Seq.init 100 pickRandomPhase - |> Seq.map (work >> Async.AwaitNodeCode) - |> Async.Parallel - |> Async.RunSynchronously - [] let ``Stress test`` () = diff --git a/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs b/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs index 75f53eb6e5c..556a9b5bc42 100644 --- a/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs +++ b/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs @@ -8,6 +8,7 @@ open Xunit open FSharp.Test open FSharp.Test.Compiler open FSharp.Compiler.BuildGraph +open FSharp.Compiler.DiagnosticsLogger open Internal.Utilities.Library module BuildGraphTests = @@ -233,3 +234,42 @@ module BuildGraphTests = Assert.shouldBeTrue graphNode.HasValue Assert.shouldBe (ValueSome 1) (graphNode.TryPeekValue()) + + + [] + let internal ``NodeCode preserves DiagnosticsThreadStatics`` () = + let random = + let rng = Random() + fun n -> rng.Next n + + let job phase _ = node { + do! random 10 |> Async.Sleep |> NodeCode.AwaitAsync + Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase) + } + + let work (phase: BuildPhase) = + node { + use _ = new CompilationGlobalsScope(DiscardErrorsLogger, phase) + let! _ = Seq.init 8 (job phase) |> NodeCode.Parallel + Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase) + } + + let phases = [| + BuildPhase.DefaultPhase + BuildPhase.Compile + BuildPhase.Parameter + BuildPhase.Parse + BuildPhase.TypeCheck + BuildPhase.CodeGen + BuildPhase.Optimize + BuildPhase.IlxGen + BuildPhase.IlGen + BuildPhase.Output + BuildPhase.Interactive + |] + + let pickRandomPhase _ = phases[random phases.Length] + Seq.init 100 pickRandomPhase + |> Seq.map (work >> Async.AwaitNodeCode) + |> Async.Parallel + |> Async.RunSynchronously