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

Make multiple attempts to remove the temporary melted save file if it's used by another process #2078

Merged
merged 1 commit into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Exceptions;
using System.Text;

public static class FileOpeningHelper {
public static class FileHelper {
private const string CloseProgramsHint = "You should close all programs that may be using the file.";

private static bool IsFilesSharingViolation(Exception ex) {
Expand Down Expand Up @@ -45,4 +45,27 @@ public static StreamWriter OpenWriteWithRetries(string filePath, Encoding encodi

return writer;
}

public static void DeleteWithRetries(string filePath) {
const int maxAttempts = 10;

int currentAttempt = 0;

var policy = Policy
.Handle<IOException>(IsFilesSharingViolation)
.WaitAndRetry(maxAttempts,
sleepDurationProvider: _ => TimeSpan.FromSeconds(30),
onRetry: (_, _, _) => {
currentAttempt++;
Logger.Warn($"Attempt {currentAttempt} to delete \"{filePath}\" failed.");
Logger.Warn(CloseProgramsHint);
});

try {
policy.Execute(() => File.Delete(filePath));
} catch (IOException ex) when (IsFilesSharingViolation(ex)) {
Logger.Debug(ex.ToString());
throw new UserErrorException($"Failed to delete \"{filePath}\". {CloseProgramsHint}");
}
}
}
3 changes: 2 additions & 1 deletion ImperatorToCK3/Helpers/RakalyCaller.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using commonItems;
using ImperatorToCK3.CommonUtils;
using ImperatorToCK3.Exceptions;
using System;
using System.ComponentModel;
Expand Down Expand Up @@ -140,7 +141,7 @@ public static void MeltSave(string savePath) {
const string destFileName = "temp/melted_save.rome";
// first, delete target file if exists, as File.Move() does not support overwrite
if (File.Exists(destFileName)) {
File.Delete(destFileName);
FileHelper.DeleteWithRetries(destFileName);
}
File.Move(meltedSaveName, destFileName);
}
Expand Down
4 changes: 2 additions & 2 deletions ImperatorToCK3/Imperator/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ private void LaunchImperatorToExportCountryFlags(Configuration config) {

string dataTypesLogPath = Path.Combine(config.ImperatorDocPath, "logs/data_types.log");
if (File.Exists(dataTypesLogPath)) {
File.Delete(dataTypesLogPath);
FileHelper.DeleteWithRetries(dataTypesLogPath);
}

Logger.Debug("Launching Imperator to extract coats of arms...");
Expand Down Expand Up @@ -218,7 +218,7 @@ private static EventHandler HandleImperatorProcessExit(Configuration config, Pro
return (_, _) => {
Logger.Debug($"Imperator process exited with code {imperatorProcess.ExitCode}. Removing temporary mod files...");
try {
File.Delete(Path.Combine(config.ImperatorDocPath, "mod/coa_export_mod.mod"));
FileHelper.DeleteWithRetries(Path.Combine(config.ImperatorDocPath, "mod/coa_export_mod.mod"));
Directory.Delete(Path.Combine(config.ImperatorDocPath, "mod/coa_export_mod"), recursive: true);
} catch (Exception e) {
Logger.Warn($"Failed to remove temporary mod files: {e.Message}");
Expand Down
6 changes: 3 additions & 3 deletions ImperatorToCK3/Outputter/BookmarkOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static async Task OutputBookmark(World world, Configuration config, CK3Lo
sb.AppendLine("}");

var path = Path.Combine("output", config.OutputModName, "common/bookmarks/bookmarks/00_bookmarks.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(path, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(path, Encoding.UTF8);
await output.WriteAsync(sb.ToString());

await DrawBookmarkMap(config, playerTitles, world);
Expand Down Expand Up @@ -141,7 +141,7 @@ Configuration config

private static async Task OutputBookmarkGroup(Configuration config) {
var path = Path.Combine("output", config.OutputModName, "common/bookmarks/groups/00_bookmark_groups.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(path, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(path, Encoding.UTF8);

await output.WriteLineAsync($"bm_converted = {{ default_start_date = {config.CK3BookmarkDate} }}");
}
Expand Down Expand Up @@ -317,6 +317,6 @@ private static async Task ResaveImageAsDDS(string imagePath) {
using (var magickImage = new MagickImage(imagePath)) {
await magickImage.WriteAsync(Path.ChangeExtension(imagePath, ".dds"));
}
File.Delete(imagePath);
FileHelper.DeleteWithRetries(imagePath);
}
}
10 changes: 5 additions & 5 deletions ImperatorToCK3/Outputter/CharactersOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ public static async Task OutputCharacters(string outputPath, CharacterCollection

var sb = new StringBuilder();
var pathForCharactersFromIR = $"{outputPath}/history/characters/IRToCK3_fromImperator.txt";
await using var charactersFromIROutput = FileOpeningHelper.OpenWriteWithRetries(pathForCharactersFromIR);
await using var charactersFromIROutput = FileHelper.OpenWriteWithRetries(pathForCharactersFromIR);
foreach (var character in charactersFromIR) {
CharacterOutputter.WriteCharacter(sb, character, conversionDate);
await charactersFromIROutput.WriteAsync(sb.ToString());
sb.Clear();
}

var pathForCharactersFromCK3 = $"{outputPath}/history/characters/IRToCK3_fromCK3.txt";
await using var charactersFromCK3Output = FileOpeningHelper.OpenWriteWithRetries(pathForCharactersFromCK3, Encoding.UTF8);
await using var charactersFromCK3Output = FileHelper.OpenWriteWithRetries(pathForCharactersFromCK3, Encoding.UTF8);
foreach (var character in charactersFromCK3) {
CharacterOutputter.WriteCharacter(sb, character, conversionDate);
await charactersFromCK3Output.WriteAsync(sb.ToString());
Expand All @@ -64,7 +64,7 @@ public static async Task BlankOutHistoricalPortraitModifiers(ModFilesystem ck3Mo

if (ck3ModFS.GetActualFileLocation(modifiersFilePath) is not null) {
string dummyPath = Path.Combine(outputPath, modifiersFilePath);
await using var output = FileOpeningHelper.OpenWriteWithRetries(dummyPath, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(dummyPath, Encoding.UTF8);
await output.WriteLineAsync("# Dummy file to blank out historical portrait modifiers from CK3.");
}
}
Expand All @@ -74,7 +74,7 @@ private static async Task OutputCharactersDNA(string outputPath, IEnumerable<Cha

// Dump all into one file.
var path = Path.Combine(outputPath, "common/dna_data/IRToCK3_dna_data.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(path, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(path, Encoding.UTF8);

var sb = new StringBuilder();
foreach (var character in charactersWithDNA) {
Expand Down Expand Up @@ -117,7 +117,7 @@ private static async Task OutputPortraitModifiers(string outputPath, IReadOnlyCo
var validAccessoryIDs = GetValidAccessoryIDs(ck3ModFS);

var portraitModifiersOutputPath = Path.Combine(outputPath, "gfx/portraits/portrait_modifiers/IRToCK3_portrait_modifiers.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(portraitModifiersOutputPath, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(portraitModifiersOutputPath, Encoding.UTF8);

await OutputPortraitModifiersForGene("hairstyles", validAccessoryIDs, charactersWithDNA, output, conversionDate);
var malesWithBeards = charactersWithDNA
Expand Down
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/CulturesOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static async Task OutputCultures(string outputModPath, CultureCollection
}

var outputPath = Path.Combine(outputModPath, "common/culture/cultures/IRtoCK3_all_cultures.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await output.WriteAsync(sb.ToString());

await OutputCultureHistory(outputModPath, cultures, date);
Expand Down
4 changes: 2 additions & 2 deletions ImperatorToCK3/Outputter/DynastiesOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static async Task OutputDynasties(string outputModPath, DynastyCollection
}

var outputPath = Path.Combine(outputModPath, "common/dynasties/irtock3_all_dynasties.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, encoding: Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(outputPath, encoding: Encoding.UTF8);
await output.WriteAsync(sb.ToString());
}

Expand All @@ -32,7 +32,7 @@ public static async Task OutputHouses(string outputModPath, HouseCollection hous
}

var outputPath = Path.Combine(outputModPath, "common/dynasty_houses/irtock3_all_houses.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, encoding: Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(outputPath, encoding: Encoding.UTF8);
await output.WriteAsync(sb.ToString());
}

Expand Down
4 changes: 2 additions & 2 deletions ImperatorToCK3/Outputter/LocalizationOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static void OutputLocalization(string outputModPath, World ck3World) {
}

var locFilePath = Path.Join(baseReplaceLocDir, language, $"converter_l_{language}.yml");
using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locFilePath, encoding: Encoding.UTF8);
using var locWriter = FileHelper.OpenWriteWithRetries(locFilePath, encoding: Encoding.UTF8);
locWriter.WriteLine(sb.ToString());
sb.Clear();
}
Expand Down Expand Up @@ -76,7 +76,7 @@ private static void OutputFallbackLocForMissingSecondaryLanguageLoc(string baseL
}

var locFilePath = Path.Combine(baseLocDir, $"{language}/irtock3_fallback_loc_l_{language}.yml");
using var locWriter = FileOpeningHelper.OpenWriteWithRetries(locFilePath, Encoding.UTF8);
using var locWriter = FileHelper.OpenWriteWithRetries(locFilePath, Encoding.UTF8);
locWriter.Write(sb.ToString());
sb.Clear();
}
Expand Down
6 changes: 3 additions & 3 deletions ImperatorToCK3/Outputter/MenAtArmsOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ private static void OutputHiddenEvent(string outputModName, IEnumerable<Characte
sb.AppendLine("}");

var outputPath = Path.Combine("output", outputModName, "events", "irtock3_hidden_events.txt");
using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8);
using var output = FileHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8);
output.Write(sb.ToString());
}

Expand All @@ -49,7 +49,7 @@ private static void OutputMenAtArmsTypes(string outputModName, IdObjectCollectio
}

var outputPath = Path.Combine("output", outputModName, "common/men_at_arms_types/IRToCK3_generated_types.txt");
using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8);
using var output = FileHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8);
output.Write(sb.ToString());
}

Expand Down Expand Up @@ -105,7 +105,7 @@ private static void OutputGuiContainer(string outputModName, ModFilesystem modFS
sb.AppendLine("}");

var outputPath = Path.Combine("output", outputModName, relativeHudTopGuiPath);
using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8);
using var output = FileHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8);
output.Write(sb.ToString());
}

Expand Down
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/NamedColorsOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static async Task OutputNamedColors(string outputModPath, NamedColorColle
sb.AppendLine("}");

var outputPath = Path.Combine(outputModPath, "common", "named_colors", "IRtoCK3_colors_from_Imperator.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await output.WriteAsync(sb.ToString());

Logger.IncrementProgress();
Expand Down
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/OnActionOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private static async Task RemoveStruggleStartFromFallenEagleOnActions(ModFilesys
}

var outputPath = $"{outputModPath}/common/on_action/TFE_game_start.txt";
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath);
await using var output = FileHelper.OpenWriteWithRetries(outputPath);
await output.WriteAsync(fileContent);
}
}
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/PillarOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static async Task OutputPillars(string outputPath, PillarCollection pilla
}

var outputFilePath = Path.Combine(outputPath, "common/culture/pillars/IRtoCK3_all_pillars.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputFilePath, System.Text.Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(outputFilePath, System.Text.Encoding.UTF8);
await output.WriteAsync(sb.ToString());
}
}
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/ProvincesOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Title.LandedTitles titles
// Create province mapping file.
if (alreadyOutputtedProvinces.Count != provinces.Count) {
var mappingsPath = $"{outputModPath}/history/province_mapping/province_mapping.txt";
await using var mappingsWriter = FileOpeningHelper.OpenWriteWithRetries(mappingsPath, System.Text.Encoding.UTF8);
await using var mappingsWriter = FileHelper.OpenWriteWithRetries(mappingsPath, System.Text.Encoding.UTF8);
await using var threadSafeWriter = TextWriter.Synchronized(mappingsWriter);

foreach (var province in provinces) {
Expand Down
4 changes: 2 additions & 2 deletions ImperatorToCK3/Outputter/ReligionsOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ private static async Task OutputHolySites(string outputModPath, ReligionCollecti
}

var outputPath = Path.Combine(outputModPath, "common/religion/holy_sites/IRtoCK3_sites.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await output.WriteAsync(sb.ToString());
sb.Clear();

Expand Down Expand Up @@ -64,7 +64,7 @@ private static async Task OutputReligions(string outputModPath, ReligionCollecti
}

var outputPath = Path.Combine(outputModPath, "common/religion/religions/IRtoCK3_all_religions.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await output.WriteAsync(sb.ToString());
}
}
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/SuccessionTriggersOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public static async Task OutputSuccessionTriggers(string outputModPath, Title.La
sb.AppendLine("}");

var outputPath = Path.Combine(outputModPath, "common/scripted_triggers/IRToCK3_succession_triggers.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(outputPath, Encoding.UTF8);
await output.WriteAsync(sb.ToString());

Logger.IncrementProgress();
Expand Down
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/TitlesOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static async Task OutputTitles(string outputModPath, Title.LandedTitles t
sb.Append(PDXSerializer.Serialize(topDeJureTitles, string.Empty, withBraces: false));

var outputPath = Path.Combine(outputModPath, "common/landed_titles/00_landed_titles.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(outputPath, System.Text.Encoding.UTF8);
await output.WriteAsync(sb.ToString());

await OutputTitlesHistory(outputModPath, titles);
Expand Down
2 changes: 1 addition & 1 deletion ImperatorToCK3/Outputter/WarsOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static async Task OutputWars(string outputModPath, IEnumerable<War> wars)
}

var path = Path.Combine(outputModPath, "history/wars/00_wars.txt");
await using var output = FileOpeningHelper.OpenWriteWithRetries(path, Encoding.UTF8);
await using var output = FileHelper.OpenWriteWithRetries(path, Encoding.UTF8);
await output.WriteAsync(sb.ToString());

Logger.IncrementProgress();
Expand Down
4 changes: 2 additions & 2 deletions ImperatorToCK3/Outputter/WorldOutputter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ private static void OutputPlaysetInfo(World ck3World, string outputModName) {

const string outFilePath = "playset_info.txt";
if (File.Exists(outFilePath)) {
File.Delete(outFilePath);
FileHelper.DeleteWithRetries(outFilePath);
}
using var output = FileOpeningHelper.OpenWriteWithRetries(outFilePath, Encoding.UTF8);
using var output = FileHelper.OpenWriteWithRetries(outFilePath, Encoding.UTF8);

foreach (var mod in modsForPlayset) {
output.WriteLine($"{mod.Name.AddQuotes()}={mod.Path.AddQuotes()}");
Expand Down
Loading