From 7c545410cc7fc58bf5ba99530cf8517f0629f308 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 21 Dec 2017 14:44:30 +0100 Subject: [PATCH] U4-10739 - retry logic in physical filesystem --- src/Umbraco.Core/IO/PhysicalFileSystem.cs | 39 +++++++++++++++++++---- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Core/IO/PhysicalFileSystem.cs b/src/Umbraco.Core/IO/PhysicalFileSystem.cs index e0fc406ff2..879f0ffe5a 100644 --- a/src/Umbraco.Core/IO/PhysicalFileSystem.cs +++ b/src/Umbraco.Core/IO/PhysicalFileSystem.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading; using Umbraco.Core.Logging; namespace Umbraco.Core.IO @@ -107,7 +108,7 @@ namespace Umbraco.Core.IO try { - Directory.Delete(fullPath, recursive); + WithRetry(() => Directory.Delete(fullPath, recursive)); } catch (DirectoryNotFoundException ex) { @@ -225,8 +226,8 @@ namespace Umbraco.Core.IO return; try - { - File.Delete(fullPath); + { + WithRetry(() => File.Delete(fullPath)); } catch (FileNotFoundException ex) { @@ -378,7 +379,7 @@ namespace Umbraco.Core.IO { if (overrideIfExists == false) throw new InvalidOperationException(string.Format("A file at path '{0}' already exists", path)); - File.Delete(fullPath); + WithRetry(() => File.Delete(fullPath)); } var directory = Path.GetDirectoryName(fullPath); @@ -386,9 +387,9 @@ namespace Umbraco.Core.IO Directory.CreateDirectory(directory); // ensure it exists if (copy) - File.Copy(physicalPath, fullPath); + WithRetry(() => File.Copy(physicalPath, fullPath)); else - File.Move(physicalPath, fullPath); + WithRetry(() => File.Move(physicalPath, fullPath)); } #region Helper Methods @@ -417,6 +418,32 @@ namespace Umbraco.Core.IO return path; } + protected void WithRetry(Action action) + { + // 10 times 100ms is 1s + const int count = 10; + const int pausems = 100; + + for (var i = 0;; i++) + { + try + { + action(); + } + catch (IOException e) + { + // if it's not *exactly* IOException then it could be + // some inherited exception such as FileNotFoundException, + // and then we don't want to retry + if (e.GetType() != typeof(IOException)) throw; + + if (i == count) throw; + // else retry + } + Thread.Sleep(pausems); + } + } + #endregion } }