Skip to content

Commit

Permalink
chore: Reworked application cleanup and exit process (Jorixon#141)
Browse files Browse the repository at this point in the history
* Reduced logging
  • Loading branch information
Jorixon authored Mar 13, 2024
1 parent 4b6399e commit da9e65f
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ private static void ValidateGameBananaUrl(Uri url)
}
catch (RateLimiterRejectedException e)
{
_logger.Debug("Rate limit exceeded, retrying after {retryAfter}", e.RetryAfter);
_logger.Verbose("Rate limit exceeded, retrying after {retryAfter}", e.RetryAfter);
var delay = e.RetryAfter ?? TimeSpan.FromSeconds(2);

await Task.Delay(delay, cancellationToken);
Expand Down
2 changes: 1 addition & 1 deletion src/GIMI-ModManager.Core/Services/SkinManagerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public async Task ScanForModsAsync()

if (!characterModFolder.Exists)
{
_logger.Debug("Character mod folder for '{Character}' does not exist", character.DisplayName);
_logger.Verbose("Character mod folder for '{Character}' does not exist", character.DisplayName);
continue;
}

Expand Down
3 changes: 3 additions & 0 deletions src/GIMI-ModManager.WinUI/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public static DirectoryInfo GetUniqueTmpFolder()
public static UIElement? AppTitlebar { get; set; }

public static bool OverrideShutdown { get; set; }
public static bool IsShuttingDown { get; set; }
public static bool ShutdownComplete { get; set; }

public static bool UnhandledExceptionHandled { get; set; }

public App()
Expand Down
123 changes: 26 additions & 97 deletions src/GIMI-ModManager.WinUI/Services/ActivationService.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
using System.Security.Principal;
using Windows.Graphics;
using CommunityToolkitWrapper;
using GIMI_ModManager.Core.Contracts.Services;
using GIMI_ModManager.Core.GamesService;
using GIMI_ModManager.Core.Helpers;
using GIMI_ModManager.WinUI.Activation;
using GIMI_ModManager.WinUI.Contracts.Services;
using GIMI_ModManager.WinUI.Helpers;
Expand Down Expand Up @@ -214,117 +212,48 @@ private async Task SetWindowSettings()
}
}

// To allow jasm to save settings before exiting, we need to handle the first close event.
// Once finished saving the handler calls itself again, but this time it will exit.
private bool _isExiting;

private async void OnApplicationExit(object sender, WindowEventArgs args)
{
if (App.OverrideShutdown)
{
_logger.Information("Shutdown override enabled, skipping shutdown...");
_logger.Information("Shutdown override will be disabled in at most 1 second.");
Task.Run(async () =>
{
await Task.Delay(500);
App.OverrideShutdown = false;
_logger.Information("Shutdown override disabled.");
});
args.Handled = true;
return;
}
if (App.ShutdownComplete) return;

if (_isExiting)
return;
args.Handled = true;

try
if (App.IsShuttingDown)
{
args.Handled = true;

var notificationCleanup = Task.Run(_modNotificationManager.CleanupAsync).ConfigureAwait(false);
var saveWindowSettingsTask = SaveWindowSettingsAsync();

_logger.Debug("JASM shutting down...");
_modUpdateAvailableChecker.CancelAndStop();
_updateChecker.CancelAndStop();
_notificationManager.CancelAndStop();

await saveWindowSettingsTask;
await _windowManagerService.CloseWindowsAsync().ConfigureAwait(false);

var tmpDir = new DirectoryInfo(App.TMP_DIR);
if (tmpDir.Exists)
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(async () =>
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
{
tmpDir.Refresh();
_logger.Debug("Deleting temporary directory: {Path}", tmpDir.FullName);
try
{
tmpDir.EnumerateFiles("*", SearchOption.AllDirectories)
.ForEach(f => f.Attributes = FileAttributes.Normal);
tmpDir.EnumerateDirectories("*", SearchOption.AllDirectories)
.ForEach(d => d.Attributes = FileAttributes.Normal);
tmpDir.Delete(true);
}
catch (Exception e)
{
_logger.Warning(e, "Failed to delete temporary directory: {Path}", tmpDir.FullName);
}
}
var softShutdownGracePeriod = TimeSpan.FromSeconds(2);
await Task.Delay(softShutdownGracePeriod);

await notificationCleanup;
_logger.Debug("JASM shutdown complete.");
}
finally
{
// Call the handler again, this time it will exit.
await Task.Run(() =>
{
_isExiting = true;
_logger.Warning(
"JASM shutdown took too long (>{maxShutdownGracePeriod}s), ignoring cleanup and exiting...",
softShutdownGracePeriod);
App.ShutdownComplete = true;
App.MainWindow.DispatcherQueue.TryEnqueue(() =>
{
Application.Current.Exit();
App.MainWindow.Close();
});
}).ConfigureAwait(false);
}
}

private async Task SaveWindowSettingsAsync()
{
if (App.MainWindow is null || App.MainWindow.AppWindow is null)
return;


var windowSettings = await _localSettingsService
.ReadOrCreateSettingAsync<ScreenSizeSettings>(ScreenSizeSettings.Key);


var isFullScreen = App.MainWindow.WindowState == WindowState.Maximized;

var width = windowSettings.Width;
var height = windowSettings.Height;
var xPosition = windowSettings.XPosition;
var yPosition = windowSettings.YPosition;

});

if (!isFullScreen && App.MainWindow.WindowState != WindowState.Minimized)
{
width = App.MainWindow.AppWindow.Size.Width;
height = App.MainWindow.AppWindow.Size.Height;
}
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(async () =>
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
{
var maxShutdownGracePeriod = TimeSpan.FromSeconds(5);
await Task.Delay(maxShutdownGracePeriod);

if (App.MainWindow.WindowState != WindowState.Minimized)
{
xPosition = App.MainWindow.AppWindow.Position.X;
yPosition = App.MainWindow.AppWindow.Position.Y;
_logger.Fatal("JASM failed to close after {maxShutdownGracePeriod} seconds, forcing exit...",
maxShutdownGracePeriod);
Environment.Exit(1);
});
return;
}

_logger.Debug($"Saving Window size: {width}x{height} | IsFullscreen: {isFullScreen}");

var newWindowSettings = new ScreenSizeSettings(width, height)
{ IsFullScreen = isFullScreen, XPosition = xPosition, YPosition = yPosition };

await _localSettingsService.SaveSettingAsync(ScreenSizeSettings.Key, newWindowSettings).ConfigureAwait(false);
await _lifeCycleService.StartShutdownAsync().ConfigureAwait(false);
}

// Declared here for now, might move to a different class later.
Expand Down
Loading

0 comments on commit da9e65f

Please sign in to comment.