Skip to content

Add retry ability to RemoveDirFixed #9409

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

Merged
merged 10 commits into from
Oct 23, 2024
Merged

Conversation

dellis1972
Copy link
Contributor

@dellis1972 dellis1972 commented Oct 16, 2024

Fixes #9133
Context: https://learn.microsoft.com/visualstudio/msbuild/copy-task?view=vs-2022

The Design Time Build (DTB) seems to lock files and directories during its build process.
This is not by design it is just that sometimes a build will try to do something with a
file that the DTB already has open.

Users will sometimes see this error.

Error (active)	XARDF7019	System.UnauthorizedAccessException: Access to the path 'GoogleGson.dll' is denied.
   at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive, Boolean throwOnTopLevelDirectoryNotFound, WIN32_FIND_DATA& data)
   at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive, Boolean checkHost)
   at Xamarin.Android.Tasks.RemoveDirFixed.RunTask() in /Users/runner/work/1/s/xamarin-android/src/Xamarin.Android.Build.Tasks/Tasks/RemoveDirFixed.cs:line 54	MauiApp2 (net9.0-android)	C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\34.99.0-preview.6.340\tools\Xamarin.Android.Common.targets	2503

PR dotnet/android-tools#245 introduced the concept on a "Retry" in the cases of UnauthorizedAccessException or IOException when the code is ACCESS_DENIED or
ERROR_SHARING_VIOLATION. This commit builds on that work to use the API's added to add retry semantics to the RemoveDirFixed task.

This also simplifys the Task somewhat as it had quite complete exception handling.

dellis1972 added a commit to dellis1972/maui that referenced this pull request Oct 18, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
@dellis1972 dellis1972 marked this pull request as ready for review October 22, 2024 16:03
dellis1972 added a commit to dellis1972/maui that referenced this pull request Oct 22, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FastDeployEnvironmentFiles(False) fails from PRs from forks, we can ignore that.

MAUI integration will also fail until they add a new feed.

@dellis1972 dellis1972 changed the title try to add retry to RemoveDirFixed Add retry ability to RemoveDirFixed Oct 23, 2024
dellis1972 added a commit to dellis1972/maui that referenced this pull request Oct 23, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
@jonpryor
Copy link
Contributor

Fixes https://github.com/dotnet/android/issues/9133

Context: https://github.com/dotnet/android-tools/commit/60fae1924e2d71f31dc1ed05f7346fd7874d6636

Much to our chagrin, in .NET 6+ it is possible for Design-Time Builds
(DTBs) to run concurrently with "normal" builds, as there is nothing
within the [.NET Project System][0] or [Common Project System (CPS)][1]
which would actively *prevent* such concurrency.

Consequently, it is possible to encounter locked files and
directories during the build process, and user may see errors such as:

	Error (active)	XARDF7019	System.UnauthorizedAccessException: Access to the path 'GoogleGson.dll' is denied.
	   at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive, Boolean throwOnTopLevelDirectoryNotFound, WIN32_FIND_DATA& data)
	   at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive, Boolean checkHost)
	   at Xamarin.Android.Tasks.RemoveDirFixed.RunTask() in /Users/runner/work/1/s/xamarin-android/src/Xamarin.Android.Build.Tasks/Tasks/RemoveDirFixed.cs:line 54	MauiApp2 (net9.0-android)	C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\34.99.0-preview.6.340\tools\Xamarin.Android.Common.targets	2503

dotnet/android-tools@60fae192 introduced the concept of a "Retry" in
the cases of `UnauthorizedAccessException`s or `IOException`s when
the code is `ACCESS_DENIED` or `ERROR_SHARING_VIOLATION`.

Builds upon that work to use the API's added to add retry semantics
to the `<RemoveDirFixed/>` task. 

This also simplifies the Task somewhat as it had quite complex
exception handling. 

[0]: https://github.com/dotnet/project-system
[1]: https://github.com/microsoft/VSProjectSystem

@jonpryor jonpryor merged commit be53aed into dotnet:main Oct 23, 2024
54 of 57 checks passed
@dellis1972 dellis1972 deleted the rmdirretry branch October 23, 2024 15:38
jonathanpeppers pushed a commit that referenced this pull request Oct 23, 2024
)

Fixes: #9133

Context: dotnet/android-tools@60fae19

Much to our chagrin, in .NET 6+ it is possible for Design-Time Builds
(DTBs) to run concurrently with "normal" builds, as there is nothing
within the [.NET Project System][0] or [Common Project System (CPS)][1]
which would actively *prevent* such concurrency.

Consequently, it is possible to encounter locked files and
directories during the build process, and user may see errors such as:

	Error (active)	XARDF7019	System.UnauthorizedAccessException: Access to the path 'GoogleGson.dll' is denied.
	   at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive, Boolean throwOnTopLevelDirectoryNotFound, WIN32_FIND_DATA& data)
	   at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive, Boolean checkHost)
	   at Xamarin.Android.Tasks.RemoveDirFixed.RunTask() in /Users/runner/work/1/s/xamarin-android/src/Xamarin.Android.Build.Tasks/Tasks/RemoveDirFixed.cs:line 54	MauiApp2 (net9.0-android)	C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\34.99.0-preview.6.340\tools\Xamarin.Android.Common.targets	2503

dotnet/android-tools@60fae192 introduced the concept of a "Retry" in
the cases of `UnauthorizedAccessException`s or `IOException`s when
the code is `ACCESS_DENIED` or `ERROR_SHARING_VIOLATION`.

Builds upon that work to use the API's added to add retry semantics
to the `<RemoveDirFixed/>` task. 

This also simplifies the Task somewhat as it had quite complex
exception handling. 

[0]: https://github.com/dotnet/project-system
[1]: https://github.com/microsoft/VSProjectSystem
dellis1972 added a commit to dellis1972/maui that referenced this pull request Oct 29, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
dellis1972 added a commit to dellis1972/maui that referenced this pull request Nov 7, 2024
… by another process

Fixes dotnet#25207
Context
dotnet/android-tools#245
dotnet/android#9409

So there is a problem where the design time builds (DTB) of android sometimes
lock files. This can happen when two processes try to write to the same
file. This is not a great experience for our users as it just fails the build.

So lets try a few things to fix this.

1. Move the Resizetizer output for a DTB into the android
`$(IntermediateOutputPath)designtime` folder. This will keep the DTB files
completely separate. This should prevent clashes.
2. Add some retry code to the `SkiaSharpTools.Save` method. This will catch
`UnauthorizedAccessException` exceptions as well as specific `IOException` types
(Access Denied and Sharing Violation). This will allow us to catch when this happens
and retry the write. There is a small delay before attempting to write the file
again.

Note these code uses the Identical code as we are going to use in Android.
We have introduced two new environment variables which can be used to
control the new behavior.

1. `DOTNET_ANDROID_FILE_WRITE_RETRY_ATTEMPTS`. Integer, controls the number of times
we try to write the file. The default is 10.
2. `DOTNET_ANDROID_FILE_WRITE_RETRY_DELAY_MS`. Integer, controls the delay in
milliseconds between retry attempts.  Default is 1000ms (or 1 second).
@github-actions github-actions bot locked and limited conversation to collaborators Nov 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UnauthorizedAccessExceptions are getting raised when building a blank MAUI app when using .NET 9.0
3 participants