Skip to content
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

CSharpier crashes when run mutliple times simultaneously #728

Closed
pingzing opened this issue Aug 26, 2022 · 2 comments · Fixed by #729
Closed

CSharpier crashes when run mutliple times simultaneously #728

pingzing opened this issue Aug 26, 2022 · 2 comments · Fixed by #729
Assignees
Labels
priority:high type:bug Something isn't working
Milestone

Comments

@pingzing
Copy link

Hi!

In my team's project, we use the CSharpier.MsBuild project for build-time formatting. We include it in all our projects by way of Directory.Build.props file in the repo root.

As of v0.19, CSharpier fails when attempting to rebuild the entire solution (about 7 projects), because multiple instances of the tool are attempting to write to the cache file, and cannot get exclusive access. Here's an example of the failure from an MSBuild log:

Target CSharpierFormat:
4>  Unhandled exception: System.IO.IOException: The process cannot access the file 'C:\Users\userdir\AppData\Local\CSharpier\.formattingCache' because it is being used by another process.
6>Target CSharpierFormat:
6>  Total time:                                                                          432ms
6>  Total files:                                                                          15
4>     at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
4>     at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
4>     at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
4>     at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
4>     at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
4>     at System.IO.File.AsyncStreamWriter(String path, Encoding encoding, Boolean append)
4>     at System.IO.File.WriteAllTextAsync(String path, String contents, Encoding encoding, CancellationToken cancellationToken)
4>     at System.IO.File.WriteAllTextAsync(String path, String contents, CancellationToken cancellationToken)
4>     at System.IO.Abstractions.FileWrapper.WriteAllTextAsync(String path, String contents, CancellationToken cancellationToken)
4>     at CSharpier.Cli.FormattingCacheFactory.FormattingCache.ResolveAsync(CancellationToken cancellationToken) in /home/runner/work/csharpier/csharpier/Src/CSharpier.Cli/FormattingCache.cs:line 113
4>     at CSharpier.Cli.CommandLineFormatter.FormatPhysicalFiles(CommandLineFormatterResult commandLineFormatterResult, CommandLineOptions commandLineOptions, IFileSystem fileSystem, IConsole console, ILogger logger, CancellationToken cancellationToken) in /home/runner/work/csharpier/csharpier/Src/CSharpier.Cli/CommandLineFormatter.cs:line 220
4>     at CSharpier.Cli.CommandLineFormatter.Format(CommandLineOptions commandLineOptions, IFileSystem fileSystem, IConsole console, ILogger logger, CancellationToken cancellationToken) in /home/runner/work/csharpier/csharpier/Src/CSharpier.Cli/CommandLineFormatter.cs:line 63
4>     at CSharpier.Cli.Program.Run(String[] directoryOrFile, Boolean check, Boolean fast, Boolean skipWrite, Boolean writeStdout, Boolean pipeMultipleFiles, Boolean noCache, CancellationToken cancellationToken) in /home/runner/work/csharpier/csharpier/Src/CSharpier.Cli/Program.cs:line 81
4>     at System.CommandLine.Invocation.CommandHandler.GetExitCodeAsync(Object value, InvocationContext context)
4>     at System.CommandLine.Invocation.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
4>     at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
4>  --- End of stack trace from previous location ---
4>     at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass23_0.<<UseParseErrorReporting>b__0>d.MoveNext()
4>  --- End of stack trace from previous location ---
4>     at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseHelp>b__0>d.MoveNext()
4>  --- End of stack trace from previous location ---
4>     at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass27_0.<<UseVersionOption>b__1>d.MoveNext()
4>  --- End of stack trace from previous location ---
4>     at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass25_0.<<UseTypoCorrections>b__0>d.MoveNext()
4>  --- End of stack trace from previous location ---
4>     at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__24_0>d.MoveNext()
4>  --- End of stack trace from previous location ---
4>     at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseParseDirective>b__0>d.MoveNext()
4>  --- End of stack trace from previous location ---
4>     at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass11_0.<<UseDebugDirective>b__0>d.MoveNext()
4>  --- End of stack trace from previous location ---
4>     at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__10_0>d.MoveNext()
4>  --- End of stack trace from previous location ---
4>     at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass14_0.<<UseExceptionHandler>b__0>d.MoveNext()
4>  C:\Users\userdir\.nuget\packages\csharpier.msbuild\0.19.0\build\CSharpier.MsBuild.targets(11,9): error MSB3073: The command "dotnet C:\Users\userdir\.nuget\packages\csharpier.msbuild\0.19.0\build\../tools/csharpier/dotnet-csharpier.dll  C:\Users\userdir\source_code\project\src\project" exited with code 1.
4

Because it's a contention issue, it can manifest with as few as two projects in a solution, but it's much more likely once you start trying to build 5 or more simultaneously.

@belav
Copy link
Owner

belav commented Aug 27, 2022

@pingzing This is fixed now in 19.1 which will be out in a bit. I was only testing the MsBuild package with a single project and don't use it regularly so completely missed this problem - going forward I'm going to use a more realistic solution to test MsBuild with.

The way this will work for now - with 7 projects all formatting at the same time, the cache may only end up including the state of the cache when the last project to build started + any files that the 7th project formatted. With repeated builds the cache will start to fill up, but it will never be completely accurate. It should still improve formatting time quite a bit. I created #730 to look into some other ways to deal with it so that MsBuild can get the full caching benefits. If you have any insight into how the MsBuild caching works in a real world situation feel free to comment there.

belav added a commit that referenced this issue Aug 27, 2022
…729)

* Potential fix for multiple processes trying to save formatting cache

closes #728

* tweaking wait logic based on more testing
@pingzing
Copy link
Author

Awesome, many thanks for the quick fix. Will update our projects next week, and report back with how it performs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority:high type:bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants