-
Notifications
You must be signed in to change notification settings - Fork 802
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
AsyncLocal part 2 - replace all ThreadStatics and remove NodeCode and node CE #16645
Conversation
❗ Release notes required
|
Yes this is still stuck on the same problem in CI. It looks like it freezes on a certain test in Linux / MacOS and something wierd also happens on Windows. ETA: The problem was Async.Sequential queues work in threadpool and this somehow causes a deadlock (probably around tcImportsLock) in some of fsharpqa Import tests involving fsi and #r requiring a dll. |
Where can I find the test that outputs stuff like
? OK I got it, it's in FsharpQA env.lst. Hmmm. |
@majocha if you'd like to, we can merge the first one, and then postpone this one a bit, I can go and try continue replacing with cold task-based one. |
@vzarytovskii I'm fine with it. I think as is, it still improves things with Transparent Compiler. |
b439ed0
to
8a070ca
Compare
OK, so this is green. It appears all of the problems with this stemmed from my oversight. NodeCode had subtly different behavior for functions like @vzarytovskii I think we can after all take this PR in favor of the #16602 I'll iron things out later. The diff is not small but reasonably easy to review. |
AsyncLocal
diagnostics part 2 - remove NodeCode
and node
CEAsyncLocal
part 2 - remove NodeCode
and node
CE, make Cancellable state AsyncLocal
AsyncLocal
part 2 - remove NodeCode
and node
CE, make Cancellable state AsyncLocal
Another diagnostics push to null, find usages with Transparent Compiler in VS:
I think there's no DiagnosticsScope here: fsharp/src/Compiler/Service/TransparentCompiler.fs Lines 641 to 643 in 3ac064e
|
Hmm, it's a question what should we do in that case. I suppose it would be nice when you search for usages, that triggers a check of some file which produces diagnostics, for them to show up in the IDE. I don't even know if we can do that in current VS extension. But eventually this could go to LSP push diagnostics. For now we can probably just add a note about it and rely on your fix with discard error logger. |
Hmm. This one doesn't seem to go through the cache. |
Oh yeah, here where it says we might need to deal with exceptions? 😅 I guess we do... fsharp/src/Compiler/Service/TransparentCompiler.fs Lines 1801 to 1802 in 3ac064e
|
We can do for now: // TODO: might need to deal with exceptions here:
let tcConfigB, sourceFileNames, _ =
DiagnosticsLogger.suppressErrorReporting <| fun () ->
ComputeTcConfigBuilder projectSnapshot |
Probably these could be just utility functions in
As they have nothing to do with Async in general. Also, naming is hard. |
A quick
|
We should probably figure out some more testing scenarios before we merge this. |
Yep, also there's a fail in CI just now. Either a bad merge or indicative of something else. |
I have a wacky idea. We could try to record changes of global (threadstatic) diagnostic logger from some compiler runs to get some kind of baseline. But that would not be deterministic. Not in a linear way, we would have to record all the forks in execution anytime there is some parallelization. That would give us some kind of tree-like baseline to compare against. Another, simpler idea is to start clean from |
Good idea. And you pretty much have it ready. Please try it and let us know. I think we can just keep that in a separate branch. |
I think we could make a draft and use that branch to systematically weed out all the weirdness, nulls etc. Eventually when all the tests pass and it runs without throwing assertions we'll know we're good. |
See #16701 |
Apart from |
This supersedes or follows up on #16602
Introduction of Transparent Compiler revealed some instability w.r.t.
DiagnosticsThreadStatics
:#16576 (comment)
#16576
#16589
Turns out we used
[<ThreadStatic>]
to keep a compilation-globalDiagnosticsLogger
, and a customNodeCode
CE to flow it across threads during execution.AsyncLocal
is a BCL class that provides exactly that functionality: flowing state along the async execution path.This replaces the
ThreadStatic
diagnostics state and Cancellable state withAsyncLocal
.NodeCode<'T>
is no longer needed, so we remove it.However
NodeCode
had some methods with subtly different behavior thanAsync
.Those are reproduced as Async type extensions in
BuildGraph.fs
.NodeCode.Sequential
->Async.SequentialImmediate
. (Because normalAsync.Sequential
queues tasks in the thread pool).NodeCode.RunImmediateWithoutCancellation
->Async.RunImmediateWithoutCancellation
.Some NodeCode methods effectively created a compilation scope, restoring previous global DiagnosticsLogger on finish:
NodeCode.FromCancellable
NodeCode.AwaitAsync
NodeCode.AwaitTask
This doesn't seem to be covered by the test suite at the moment. (All the tests pass with or without) but the following extensions wrap the computation in
use _ = new CompilationGlobalsScope(...
preserving and restoring globals:Async.FromCancellableWithScope
Async.CompilationScope