Skip to content

Commit

Permalink
TransientIO: Catch exception after retrying.
Browse files Browse the repository at this point in the history
Fixes #1040.
  • Loading branch information
am11 committed May 13, 2014
1 parent 8bc5162 commit 860721d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public static class PolicyFactory
{
public static RetryPolicy GetPolicy(ITransientErrorDetectionStrategy strategy, int retryCount)
{
RetryPolicy policy = new RetryPolicy(strategy, retryCount, TimeSpan.FromMilliseconds(50));
RetryPolicy policy = new RetryPolicy(strategy, retryCount, TimeSpan.FromMilliseconds(50), TimeSpan.FromMilliseconds(50));

return policy;
}
Expand Down
81 changes: 46 additions & 35 deletions EditorExtensions/Shared/Helpers/FileHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,19 @@ public static void SearchFiles(string term, string fileTypes)
/// <returns>Task which ultimately returns a string containing all lines of the file.</returns>
public async static Task<string> ReadAllTextRetry(string fileName)
{
return await BeginRead<string>(Task.FromResult<string>(File.ReadAllText(fileName))
.ExecuteRetryableTaskAsync<string>(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), 5)));
int retryCount = 500;

try
{
return await Task.FromResult<string>(File.ReadAllText(fileName))
.ExecuteRetryableTaskAsync<string>(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), retryCount));
}
catch (IOException)
{
Logger.Log("Exception: Tried " + retryCount + " times for reading, but the file " + fileName + " is still in use. Exiting gracefully.");
}

return string.Empty;
}

/// <summary>
Expand All @@ -311,8 +322,19 @@ public async static Task<string> ReadAllTextRetry(string fileName)
/// <returns>Task which ultimately returns all lines of the file, or the lines that are the result of a query.</returns>
public async static Task<IEnumerable<string>> ReadAllLinesRetry(string fileName)
{
return await BeginRead<IEnumerable<string>>(Task.FromResult<IEnumerable<string>>(File.ReadLines(fileName))
.ExecuteRetryableTaskAsync<IEnumerable<string>>(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), 5)));
int retryCount = 500;

try
{
return await Task.FromResult<IEnumerable<string>>(File.ReadLines(fileName))
.ExecuteRetryableTaskAsync<IEnumerable<string>>(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), retryCount));
}
catch (IOException)
{
Logger.Log("Exception: Tried " + retryCount + " times for reading, but the file " + fileName + " is still in use. Exiting gracefully.");
}

return Enumerable.Empty<string>();
}

/// <summary>
Expand All @@ -324,28 +346,19 @@ public async static Task<IEnumerable<string>> ReadAllLinesRetry(string fileName)
/// <returns>Task which ultimately returns all lines of the file, or the lines that are the result of a query.</returns>
public async static Task<byte[]> ReadAllBytesRetry(string fileName)
{
return await BeginRead<byte[]>(Task.FromResult<byte[]>(File.ReadAllBytes(fileName))
.ExecuteRetryableTaskAsync<byte[]>(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), 5)));
}

private async static Task<T> BeginRead<T>(Task<T> readTask, int count = 0)
{
bool exception = false;
T text = default(T);
int retryCount = 500;

try
{
text = await readTask;
return await Task.FromResult<byte[]>(File.ReadAllBytes(fileName))
.ExecuteRetryableTaskAsync<byte[]>(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), retryCount));
}
catch (IOException)
{
if (count > 10000)
return text;

exception = true;
Logger.Log("Exception: Tried " + retryCount + " times for reading, but the file " + fileName + " is still in use. Exiting gracefully.");
}

return exception ? await BeginRead(readTask, ++count) : text;
return Enumerable.Empty<byte>().ToArray();
}

/// <summary>
Expand All @@ -357,8 +370,17 @@ private async static Task<T> BeginRead<T>(Task<T> readTask, int count = 0)
/// <param name="contents">The string to write to the file.</param>
public async static Task WriteAllTextRetry(string fileName, string contents)
{
await BeginWrite(Task.Run(() => File.WriteAllText(fileName, contents, Encoding.UTF8))
.ExecuteRetryableTaskAsync(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), 5)));
int retryCount = 500;

try
{
await Task.Run(() => File.WriteAllText(fileName, contents, Encoding.UTF8))
.ExecuteRetryableTaskAsync(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), retryCount));
}
catch (IOException)
{
Logger.Log("Exception: Tried " + retryCount + " times for writing, but the file " + fileName + " is still in use. Exiting gracefully.");
}
}

/// <summary>
Expand All @@ -370,28 +392,17 @@ await BeginWrite(Task.Run(() => File.WriteAllText(fileName, contents, Encoding.U
/// <param name="value">The bytes to write to the file.</param>
public async static Task WriteAllBytesRetry(string fileName, byte[] value)
{
await BeginWrite(Task.Run(() => File.WriteAllBytes(fileName, value))
.ExecuteRetryableTaskAsync(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), 5)));
}

private async static Task BeginWrite(Task writeTask, int count = 0)
{
bool exception = false;
int retryCount = 500;

try
{
await writeTask;
await Task.Run(() => File.WriteAllBytes(fileName, value))
.ExecuteRetryableTaskAsync(PolicyFactory.GetPolicy(new FileTransientErrorDetectionStrategy(), retryCount));
}
catch (IOException)
{
if (count > 10000)
return;

exception = true;
Logger.Log("Exception: Tried" + retryCount + " times for writing, but the file " + fileName + " is still in use. Exiting gracefully.");
}

if (exception)
await BeginWrite(writeTask, ++count);
}

/// <summary>
Expand Down

0 comments on commit 860721d

Please sign in to comment.