-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Rationalize how temporary directory works today #68226
Conversation
d87e52d
to
eca53ed
Compare
@dotnet/roslyn-compiler PTAL |
Since we don't want analyzers/generators doing I/O generally, it follows that we don't want them using temp directories for scratch space, etc., right? |
Most definitely. If that's not o nthe banned list yet it needs to be. |
This field is now duplicated in the base class. As an alternative, what if we remove the field from the base class and remove Refers to: src/Compilers/Core/Portable/CommandLine/CommonCompiler.CompilerEmitStreamProvider.cs:24 in eca53ed. [](commit_id = eca53ed, deletion_comment = False) |
src/Compilers/CSharp/Test/Emit/Emit/DesktopStrongNameProviderTests.cs
Outdated
Show resolved
Hide resolved
@@ -45,8 +45,6 @@ public void Close(DiagnosticBag diagnostics) | |||
} | |||
} | |||
|
|||
public override Stream? Stream => null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this related to the PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. The virtual member was removed in the base type.
The reason for this part of the change is I had a lot of time understanding the relationship between the EmitStreamProvider
and underlying Stream
. Particularly when do they get created and what is the ownership model.
A significant part of this change was figuring out exactly where the files were created and destroyed hence as part of the fix I tried to make this much clearer.
Happy for feedback on the new approach.
src/Compilers/VisualBasic/Test/Emit/Attributes/EmitTestStrongNameProvider.vb
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit2/Attributes/InternalsVisibleToAndStrongNameTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit2/Attributes/InternalsVisibleToAndStrongNameTests.cs
Show resolved
Hide resolved
.vscode/settings.json
Outdated
@@ -1,38 +0,0 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this deletion related to the goal of the PR?
@RikkiGibson FYI i pushed on more commit that had functional impact. In reviewing my change this morning and thinking about the followup change I realized I'd error'd in one place. Specifically not sending compilation requests to the server when the request cannot calculate a temporary directory. Originally I did that under the logic of the server can't start if there is a missing temp directory so what's the point. I now realize that was wrong for two reasons:
Once I start on the next change I'm goingto add the fast fail code for the missing temp dir case. It's an extreme edge anyways. |
Got it, so you just reverted the check to ensure client can get a temp directory before sending the build request? And in a subsequent PR you'll add some new check to ensure the server fails in a clear/actionable way when it can't create a temp directory? |
Before fixing dotnet#65415 I needed to better rationalize how `Path.GetTempPath` and temp paths in general worked in the compiler. This change ended up addressing the following problems: **Path.GetTempPath** `Path.GetTempPath` should never be used in the compiler libraries. That uses a number of environment variables, like working directory, that can change during the lifetime of a build operation. That makes compilation non-deterministic and can lead to sporadic errors. All uses of `GetTempPath` need to come from the initial csc / vbc invocation and be passed through as arguments. This was solved by adding a new BannedSymbols file for compiler libraries that banned `Path.GetTempPath` and working through the remaining case I found. This introduced one new error because `Path.GetTempPath` was being used as a fall back in legacy signing if csc / vbc couldn't calculate a temp path at invocation time. This is a "this should never actually happen" problem but I added an error code as a precaution. I did not force the temp directory to non-null for all compilations because the vast majority of compilations don't actually need a temp directory. It is only used in legacy signing which is very rare. **Where is temp required** It was unclear in our code base where a temp directory was actually required for execution. To get a better handle on this, now and going forward, I enabled NRT in files that handled temp directories. After working through it there are only two cases where it's required: 1. When using legacy strong named signing. 2. When starting the compiler server. For (2) it's required as a place to shadow copy analyzers / generators. There is no reasonable fall back if the server can't calculate a temp path. Further if the client can't calculate a temp path then there is a very strong chance (basically guaranteed) that the server can't either. Therefore I added a few places where we simply don't even try to communicate with the compiler server if we can't find a temporary directory. Basically fail fast vs. failing slow. Once this change is in I can move forward with dotnet#65415. The impact of that change will be much clearer after this goes through because it changes both what we depend on and where shadow copy happens.
Before fixing #65415 I needed to better rationalize how
Path.GetTempPath
and temp paths in general worked in the compiler.This change ended up addressing the following problems:
Path.GetTempPath
Path.GetTempPath
should never be used in the compiler libraries.That uses a number of environment variables, like working directory,
that can change during the lifetime of a build operation. That makes
compilation non-deterministic and can lead to sporadic errors. All
uses of
GetTempPath
need to come from the initial csc / vbcinvocation and be passed through as arguments.
This was solved by adding a new BannedSymbols file for compiler
libraries that banned
Path.GetTempPath
and working through theremaining case I found.
This introduced one new error because
Path.GetTempPath
was being usedas a fall back in legacy signing if csc / vbc couldn't calculate a
temp path at invocation time. This is a "this should never actually
happen" problem but I added an error code as a precaution.
I did not force the temp directory to non-null for all compilations
because the vast majority of compilations don't actually need a temp
directory. It is only used in legacy signing which is very rare.
Where is temp required
It was unclear in our code base where a temp directory was actually
required for execution. To get a better handle on this, now and going
forward, I enabled NRT in files that handled temp directories. After
working through it there are only two cases where it's required:
For (2) it's required as a place to shadow copy analyzers /
generators. There is no reasonable fall back if the server can't
calculate a temp path. Further if the client can't calculate a temp path
then there is a very strong chance (basically guaranteed) that the
server can't either. Therefore I added a few places where we simply
don't even try to communicate with the compiler server if we can't find
a temporary directory. Basically fail fast vs. failing slow.
Once this change is in I can move forward with #65415. The impact of
that change will be much clearer after this goes through because it
changes both what we depend on and where shadow copy happens.